Pre-include LSS

This commit is contained in:
Liam 2023-10-05 20:06:38 -04:00
parent d649b2a3fd
commit c89f9dddc7
21 changed files with 6438 additions and 1 deletions

1
.gitignore vendored
View File

@ -87,5 +87,4 @@ src/Makefile
# Ignore directories gclient syncs.
src/testing
src/third_party/lss
src/third_party/protobuf

3
src/third_party/lss/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
*.o
core

12
src/third_party/lss/DIR_METADATA vendored Normal file
View File

@ -0,0 +1,12 @@
# Metadata information for this directory.
#
# For more information on DIR_METADATA files, see:
# https://source.chromium.org/chromium/infra/infra/+/HEAD:go/src/infra/tools/dirmd/README.md
#
# For the schema of this file, see Metadata message:
# https://source.chromium.org/chromium/infra/infra/+/HEAD:go/src/infra/tools/dirmd/proto/dir_metadata.proto
os: LINUX
monorail {
project: "linux-syscall-support"
}

27
src/third_party/lss/LICENSE vendored Normal file
View File

@ -0,0 +1,27 @@
Copyright 2005-2011 Google LLC
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 LLC nor the names of its
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.

2
src/third_party/lss/OWNERS vendored Normal file
View File

@ -0,0 +1,2 @@
mseaborn@chromium.org
vapier@chromium.org

138
src/third_party/lss/README.md vendored Normal file
View File

@ -0,0 +1,138 @@
# Linux Syscall Support (LSS)
Every so often, projects need to directly embed Linux system calls instead of
calling the implementations in the system runtime library.
This project provides a header file that can be included into your application
whenever you need to make direct system calls.
The goal is to provide an API that generally mirrors the standard C library
while still making direct syscalls. We try to hide some of the differences
between arches when reasonably feasible. e.g. Newer architectures no longer
provide an `open` syscall, but do provide `openat`. We will still expose a
`sys_open` helper by default that calls into `openat` instead.
We explicitly do not expose the raw syscall ABI including all of its historical
warts to the user. We want people to be able to easily make a syscall, not have
to worry that on some arches size args are swapped or they are shifted.
Please be sure to review the Caveats section below however.
## How to include linux\_syscall\_support.h in your project
You can either copy the file into your project, or preferably, you can set up
Git submodules to automatically pull from our source repository.
## Supported targets
The following architectures/ABIs have been tested (at some point) and should
generally work. If you don't see your combo listed here, please double check
the header itself as this list might be out of date.
* x86 32-bit (i.e. i386, i486, i586, i686, Intel, AMD, etc...)
* [x86_64 64-bit](https://en.wikipedia.org/wiki/X86-64) (i.e. x86-64, amd64, etc...)
* [x32 32-bit](https://sites.google.com/site/x32abi/)
* [ARM 32-bit](https://en.wikipedia.org/wiki/ARM_architecture) OABI
* [ARM 32-bit](https://en.wikipedia.org/wiki/ARM_architecture) EABI (i.e. armv6, armv7, etc...)
* AARCH64 64-bit (i.e. arm64, armv8, etc...)
* PowerPC 32-bit (i.e. ppc, ppc32, etc...)
* MIPS 32-bit o32 ABI
* MIPS 32-bit n32 ABI
* MIPS 64-bit n64 ABI
* LOONGARCH 64-bit ABI
## API
By default, you can just add a `sys_` prefix to any function you want to call.
So if you want to call `open(...)`, use `sys_open(...)` instead.
### Knobs
The linux\_syscall\_support.h header provides many knobs for you to control
the exported API. These are all documented in the top of the header in a big
comment block, so refer to that instead.
## Caveats
### ABI differences
Some functions that the standard C library exposes use a different ABI than
what the Linux kernel uses. Care must be taken when making syscalls directly
that you use the right structure and flags. e.g. Most C libraries define a
`struct stat` (commonly in `sys/stat.h` or `bits/stat.h`) that is different
from the `struct stat` the kernel uses (commonly in `asm/stat.h`). If you use
the wrong structure layout, then you can see errors like memory corruption or
weird/shifted values. If you plan on making syscalls directly, you should
focus on headers that are available under the `linux/` and `asm/` namespaces.
Note: LSS provides structs for most of these cases. For `sys_stat()`, it
provides `struct kernel_stat` for you to use.
### Transparent backwards compatibility with older kernels
While some C libraries (notably, glibc) take care to fallback to older syscalls
when running on older kernels, there is no such support in LSS. If you plan on
trying to run on older kernels, you will need to handle errors yourself (e.g.
`ENOSYS` when using a too new syscall).
Remember that this can happen with new flag bits too. e.g. The `O_CLOEXEC`
flag was added to many syscalls, but if you try to run use it on older kernels,
it will fail with `EINVAL`. In that case, you must handle the fallback logic
yourself.
### Variable arguments (varargs)
We do not support vararg type functions. e.g. While the standard `open()`
function can accept 2 or 3 arguments (with the mode field being optional),
the `sys_open()` function always requires 3 arguments.
## Bug reports & feature requests
If you wish to report a problem or request a feature, please file them in our
[bug tracker](https://bugs.chromium.org/p/linux-syscall-support/issues/).
Please do not post patches to the tracker. Instead, see below for how to send
patches to us directly.
While we welcome feature requests, please keep in mind that it is unlikely that
anyone will find time to implement them for you. Sending patches is strongly
preferred and will often move things much faster.
## Projects that use LSS
* [Chromium](https://www.chromium.org/)
* [Breakpad](https://chromium.googlesource.com/breakpad/breakpad)
* [Native Client](https://developer.chrome.com/native-client), in nacl\_bootstrap.c
## How to get an LSS change committed
### Review
You get your change reviewed, you can upload it to
[Gerrit](https://chromium-review.googlesource.com/q/project:linux-syscall-support+status:open)
using `git cl upload` from
[Chromium's depot-tools](https://commondatastorage.googleapis.com/chrome-infra-docs/flat/depot_tools/docs/html/depot_tools_tutorial.html).
### Testing
Tests are found in the [tests/](./tests/) subdirectory. It does not (yet) offer
100% coverage, but should grow over time.
New commits that update/change/add syscall wrappers should include tests for
them too. Consult the [test documentation](./tests/README.md) for more details.
To run, just run `make` inside the tests directory. It will compile & execute
the tests locally.
There is some limited cross-compile coverage available if you run `make cross`.
It only compiles things (does not execute at all).
### Rolling into Chromium
If you commit a change to LSS, please also commit a Chromium change to update
`lss_revision` in
[Chromium's DEPS](https://chromium.googlesource.com/chromium/src/+/HEAD/DEPS)
file.
This ensures that the LSS change gets tested, so that people who commit later
LSS changes don't run into problems with updating `lss_revision`.

View File

@ -0,0 +1,5 @@
# This file is used by git cl to get repository specific information.
CC_LIST: chromium-reviews@chromium.org,mseaborn@chromium.org
CODE_REVIEW_SERVER: codereview.chromium.org
GERRIT_HOST: True
VIEW_VC: https://chromium.googlesource.com/linux-syscall-support/+/

File diff suppressed because it is too large Load Diff

4
src/third_party/lss/tests/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
/*_test
# Some tests create temp files.
/tempfile.*

147
src/third_party/lss/tests/Makefile vendored Normal file
View File

@ -0,0 +1,147 @@
# Copyright 2018 Google LLC
#
# 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 LLC nor the names of its
# 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.
top_srcdir ?= ..
DEF_FLAGS = -g -pipe
DEF_WFLAGS = -Wall
CFLAGS ?= $(DEF_FLAGS)
CXXFLAGS ?= $(DEF_FLAGS)
CFLAGS += $(DEF_WFLAGS) -Wstrict-prototypes
CXXFLAGS += $(DEF_WFLAGS)
CPPFLAGS += -I$(top_srcdir)
# We use static linking here so that if people run through qemu/etc... by hand,
# it's a lot easier to run/debug. Same for strace output.
LDFLAGS += -static
TESTS = \
fallocate \
getitimer \
getrandom \
lstat \
setitimer \
sigaction \
sigtimedwait \
stat \
unlink \
all: check
%_test: %.c test_skel.h $(top_srcdir)/linux_syscall_support.h
$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -o $@ $<
# Force building C as C++ code to improve compile-time coverage.
%_cc_test: %.c test_skel.h $(top_srcdir)/linux_syscall_support.h
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) -o $@ $<
%_test: %.cc test_skel.h $(top_srcdir)/linux_syscall_support.h
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) -o $@ $<
%_run: %_test
@t=$(@:_run=_test); \
echo "./$$t"; \
env -i ./$$t; \
exit_status=$$?; \
if [ $$exit_status = 77 ]; then \
echo "SKIP: $$t"; \
elif [ $$exit_status != 0 ]; then \
echo "FAIL: $$t"; \
env -i strace -f -v ./$$t; \
echo "TRY: gdb -q -ex r -ex bt ./$$t"; \
exit 1; \
fi
ALL_TEST_TARGETS = $(TESTS:=_test) $(TESTS:=_cc_test)
compile_tests: $(ALL_TEST_TARGETS)
ALL_RUN_TARGETS = $(TESTS:=_run) $(TESTS:=_cc_run)
check: $(ALL_RUN_TARGETS)
# The "tempfile" targets are the names we use with temp files.
# Clean them out in case some tests crashed in the middle.
clean:
rm -f *~ *.o tempfile.* a.out core $(ALL_TEST_TARGETS)
.SUFFIXES:
.PHONY: all check clean compile_tests
.SECONDARY: $(ALL_TEST_TARGETS)
# Try to cross-compile the tests for all our supported arches. We test with
# both gcc and clang. We don't support execution (yet?), but just compiling
# & linking helps catch common bugs.
.PHONY: cross compile_cross
cross_compile:
@echo "Running: $(MAKE) $@ CC='$(CC)' CXX='$(CXX)'"; \
if (echo '#include <stdio.h>' | $(CC) -x c -c -o /dev/null -) 2>/dev/null; then \
$(MAKE) -s clean; \
$(MAKE) -k --no-print-directory compile_tests; \
else \
echo "Skipping $(CC) test: not installed"; \
fi; \
echo
# The names here are a best effort. Not easy to probe for.
cross:
@for cc in \
"x86_64-pc-linux-gnu-gcc" \
"i686-pc-linux-gnu-gcc" \
"x86_64-pc-linux-gnu-gcc -mx32" \
"armv7a-unknown-linux-gnueabi-gcc -marm -mhard-float" \
"armv7a-unknown-linux-gnueabi-gcc -mthumb -mhard-float" \
"powerpc-unknown-linux-gnu-gcc" \
"aarch64-unknown-linux-gnu-gcc" \
"mips64-unknown-linux-gnu-gcc -mabi=64" \
"mips64-unknown-linux-gnu-gcc -mabi=32" \
"mips64-unknown-linux-gnu-gcc -mabi=n32" \
"s390-ibm-linux-gnu-gcc" \
"s390x-ibm-linux-gnu-gcc" \
"loongarch64-unknown-linux-gnu-gcc" \
; do \
cxx=`echo "$$cc" | sed 's:-gcc:-g++:'`; \
$(MAKE) --no-print-directory CC="$$cc" CXX="$$cxx" cross_compile; \
\
sysroot=`$$cc --print-sysroot 2>/dev/null`; \
gccdir=`$$cc -print-file-name=libgcc.a 2>/dev/null`; \
gccdir=`dirname "$$gccdir"`; \
: Skip building for clang for mips/o32 and s390/31-bit until it works.; \
case $$cc in \
mips64*-mabi=32) continue;; \
s390-*) continue;; \
esac; \
set -- $$cc; \
tuple=$${1%-gcc}; \
shift; \
cc="clang -target $$tuple $$*"; \
: Assume the build system is x86_64 based, so ignore the sysroot.; \
case $$tuple in \
x86_64*) ;; \
*) cc="$$cc --sysroot $$sysroot -B$$gccdir -L$$gccdir";; \
esac; \
cxx=`echo "$$cc" | sed 's:^clang:clang++:'`; \
$(MAKE) --no-print-directory CC="$$cc" CXX="$$cxx" cross_compile; \
done

52
src/third_party/lss/tests/README.md vendored Normal file
View File

@ -0,0 +1,52 @@
# LSS Tests
## Source Layout
The general layout of the tests:
* [test_skel.h]: Test helpers for common checks/etc...
* xxx.c: Unittest for the xxx syscall (e.g. `open.c`).
* [Makefile]: New tests should be registered in the `TESTS` variable.
## Test Guidelines
The unittest itself generally follows the conventions:
* Written in C (unless a very specific language behavior is needed).
* You should only need to `#include "test_skel.h"`. For new system headers, try
to add them here rather than copying to exact unittest (if possible).
It might slow compilation down slightly, but makes the code easier to manage.
Make sure it is included first.
* Use `assert()` on everything to check return values.
* Use `sys_xxx()` to access the syscall via LSS (compared to `xxx()` which tends
to come from the C library).
* If you need a tempfile, use `tempfile.XXXXXX` for templates with helpers like
`mkstemp`. Try to clean them up when you're done with them.
These will be created in the cwd, but that's fine.
* Don't worry about trying to verify the kernel/C library API and various edge
cases. The goal of LSS is to make sure that we pass args along correctly to
the syscall only.
* Make sure to leave comments in the test so it's clear what behavior you're
trying to verify (and how).
Feel free to extend [test_skel.h] with more helpers if they're useful to more
than one test.
If you're looking for a simple example, start with [unlink.c](./unlink.c).
You should be able to copy this over and replace the content of `main()`.
## Running The Tests
Simply run `make`. This will compile & execute all the tests on your local
system. A standard `make clean` will clean up all the objects.
If you need to debug something, then the programs are simply named `xxx_test`
and can easily be thrown into `gdb ./xxx_test`.
We have rudimentary cross-compile testing via gcc and clang. Try running
`make cross` -- for any toolchains you don't have available, it should skip
things automatically. This only verifies the compilation & linking stages
though.
The cross-compilers can be created using <http://crosstool-ng.github.io/>.
[Makefile]: ./Makefile
[test_skel.h]: ./test_skel.h

69
src/third_party/lss/tests/fallocate.c vendored Normal file
View File

@ -0,0 +1,69 @@
/* Copyright 2019 Google LLC
*
* 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 LLC nor the names of its
* 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 "test_skel.h"
int main(int argc, char *argv[]) {
int fd = 0, mode = 0;
loff_t offset = 0, len = 0;
// Bad file descriptor.
fd = -1;
assert(sys_fallocate(fd, mode, offset, len) == -1);
assert(errno == EBADF);
char filename[] = "tempfile.XXXXXX";
fd = mkstemp(filename);
assert(fd >= 0);
// Invalid len.
assert(sys_fallocate(fd, mode, offset, len) == -1);
assert(errno == EINVAL);
// Small offset and length succeeds.
len = 4096;
assert(sys_fallocate(fd, mode, offset, len) == 0);
// Large offset succeeds and isn't truncated.
offset = 1llu + UINT32_MAX;
assert(sys_fallocate(fd, mode , offset, len) == 0);
#if defined(__NR_fstat64)
struct kernel_stat64 st;
assert(sys_fstat64(fd, &st) == 0);
#else
struct kernel_stat st;
assert(sys_fstat(fd, &st) == 0);
#endif
assert(st.st_size == offset + len);
sys_unlink(filename);
return 0;
}

84
src/third_party/lss/tests/getitimer.c vendored Normal file
View File

@ -0,0 +1,84 @@
/* Copyright 2022 Google LLC
*
* 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 LLC nor the names of its
* 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 "test_skel.h"
int main(int argc, char *argv[]) {
// We need an invalid timer value. The assert()'s below should
// be static asserts but it is not available in older C versions.
#define kInvalidTimer 9999
assert(kInvalidTimer != ITIMER_REAL);
assert(kInvalidTimer != ITIMER_VIRTUAL);
assert(kInvalidTimer != ITIMER_PROF);
// This should fail with EINVAL.
struct kernel_itimerval curr_itimer;
assert(sys_getitimer(kInvalidTimer, &curr_itimer) == -1);
assert(errno == EINVAL);
// Create a read-only page.
size_t page_size = getpagesize();
void* read_only_page = sys_mmap(NULL, page_size, PROT_READ,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
assert(read_only_page != MAP_FAILED);
// This should fail with EFAULT.
assert(sys_getitimer(ITIMER_REAL,
(struct kernel_itimerval*) read_only_page) == -1);
assert(errno == EFAULT);
// This should complete without an error.
assert(sys_getitimer(ITIMER_REAL, &curr_itimer) == 0);
// Set up a real time timer with very long interval and value so that
// we do not need to handle SIGALARM in test.
struct kernel_itimerval new_itimer;
const time_t kIntervalSec = 60 * 60 * 24 * 365; // One year.
const long kIntervalUSec = 123;
new_itimer.it_interval.tv_sec = kIntervalSec;
new_itimer.it_interval.tv_usec = kIntervalUSec;
new_itimer.it_value = new_itimer.it_interval;
assert(sys_setitimer(ITIMER_REAL, &new_itimer, NULL) == 0);
assert(sys_getitimer(ITIMER_REAL, &curr_itimer) == 0);
assert(kernel_timeval_eq(&curr_itimer.it_interval, &new_itimer.it_interval));
// Disable timer.
struct kernel_itimerval empty_itimer;
empty_itimer.it_interval.tv_sec = 0;
empty_itimer.it_interval.tv_usec = 0;
empty_itimer.it_value = empty_itimer.it_interval;
assert(sys_setitimer(ITIMER_REAL, &empty_itimer, NULL) == 0);
// We should read back an empty itimer.
assert(sys_getitimer(ITIMER_REAL, &curr_itimer) == 0);
assert(kernel_itimerval_eq(&curr_itimer, &empty_itimer));
return 0;
}

59
src/third_party/lss/tests/getrandom.c vendored Normal file
View File

@ -0,0 +1,59 @@
/* Copyright 2020 Google LLC
*
* 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 LLC nor the names of its
* 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 "test_skel.h"
#define BUFFER_SIZE 256
int main(int argc, char *argv[]) {
char buffer[BUFFER_SIZE];
// Zero it out so we can check later that it's at least not all 0s.
memset(buffer, 0, BUFFER_SIZE);
bool buffer_contains_all_zeros = true;
// Don't bother passing any flags. (If we're using lss, we might not have the
// right header files with the flags defined anyway, and we'd have to copy
// this in here too, and risk getting out of sync in yet another way.)
const ssize_t r = sys_getrandom(buffer, BUFFER_SIZE, 0);
// Make sure it either worked, or that it's just not supported.
assert(r == BUFFER_SIZE || errno == ENOSYS);
if (r == BUFFER_SIZE) {
// If all the bytes are 0, it didn't really work.
for (size_t i = 0; i < BUFFER_SIZE; ++i) {
if (buffer[i] != 0) {
buffer_contains_all_zeros = false;
}
}
assert(!buffer_contains_all_zeros);
}
return 0;
}

97
src/third_party/lss/tests/lstat.c vendored Normal file
View File

@ -0,0 +1,97 @@
/* Copyright 2021 Google LLC
*
* 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 LLC nor the names of its
* 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 "test_skel.h"
int main(int argc, char *argv[]) {
int exit_status = 0;
// Get two unique paths to play with.
char foo[] = "tempfile.XXXXXX";
char bar[] = "tempfile.XXXXXX";
int fd_foo = mkstemp(foo);
int fd_bar = mkstemp(bar);
assert(fd_foo != -1);
assert(fd_bar != -1);
// Then delete foo.
assert(sys_unlink(foo) == 0);
// Now make foo a symlink to bar.
assert(symlink(bar, foo) == 0);
// Make sure sys_stat() and sys_lstat() implementation return different
// information.
// We need to check our stat syscalls for EOVERFLOW, as sometimes the integer
// types used in the stat structures are too small to fit the actual value.
// E.g. on some systems st_ino is 32-bit, but some filesystems have 64-bit
// inodes.
struct kernel_stat lstat_info;
int rc = sys_lstat(foo, &lstat_info);
if (rc < 0 && errno == EOVERFLOW) {
// Bail out since we had an overflow in the stat structure.
exit_status = SKIP_TEST_EXIT_STATUS;
goto cleanup;
}
assert(rc == 0);
struct kernel_stat stat_info;
rc = sys_stat(foo, &stat_info);
if (rc < 0 && errno == EOVERFLOW) {
// Bail out since we had an overflow in the stat structure.
exit_status = SKIP_TEST_EXIT_STATUS;
goto cleanup;
}
assert(rc == 0);
struct kernel_stat bar_stat_info;
rc = sys_stat(bar, &bar_stat_info);
if (rc < 0 && errno == EOVERFLOW) {
// Bail out since we had an overflow in the stat structure.
exit_status = SKIP_TEST_EXIT_STATUS;
goto cleanup;
}
assert(rc == 0);
// lstat should produce information about a symlink.
assert((lstat_info.st_mode & S_IFMT) == S_IFLNK);
// stat-ing foo and bar should produce the same inode.
assert(stat_info.st_ino == bar_stat_info.st_ino);
// lstat-ing foo should give a different inode than stat-ing foo.
assert(stat_info.st_ino != lstat_info.st_ino);
cleanup:
sys_unlink(foo);
sys_unlink(bar);
return exit_status;
}

90
src/third_party/lss/tests/setitimer.c vendored Normal file
View File

@ -0,0 +1,90 @@
/* Copyright 2022 Google LLC
*
* 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 LLC nor the names of its
* 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 "test_skel.h"
int main(int argc, char *argv[]) {
// We need an invalid timer value. The assert()'s below should
// be static asserts but it is not avalible in older C versions.
#define kInvalidTimer 9999
assert(kInvalidTimer != ITIMER_REAL);
assert(kInvalidTimer != ITIMER_VIRTUAL);
assert(kInvalidTimer != ITIMER_PROF);
// Invalid timer returns EINVAL.
assert(sys_setitimer(kInvalidTimer, NULL, NULL) == -1);
assert(errno == EINVAL);
const int kSignal = SIGALRM;
const size_t kSigsetSize = sizeof(struct kernel_sigset_t);
// Block SIGALRM.
struct kernel_sigset_t sigalarm_only;
struct kernel_sigset_t old_sigset;
assert(sys_sigemptyset(&sigalarm_only) == 0);
assert(sys_sigaddset(&sigalarm_only, kSignal) == 0);
assert(sys_rt_sigprocmask(SIG_BLOCK, &sigalarm_only, &old_sigset,
kSigsetSize) == 0);
// Set up a real time timer.
struct kernel_itimerval new_itimer = {};
const long kIntervalUSec = 123;
new_itimer.it_interval.tv_sec = 0;
new_itimer.it_interval.tv_usec = kIntervalUSec;
new_itimer.it_value = new_itimer.it_interval;
assert(sys_setitimer(ITIMER_REAL, &new_itimer, NULL) == 0);
// Wait for alarm.
struct timespec timeout;
const unsigned long kNanoSecsPerSec = 1000000000;
const unsigned long kNanoSecsPerMicroSec = 1000;
// Use a timeout 3 times of the timer interval.
unsigned long duration_ns = kIntervalUSec * kNanoSecsPerMicroSec * 3;
timeout.tv_sec = duration_ns / kNanoSecsPerSec ;
timeout.tv_nsec = duration_ns % kNanoSecsPerSec;
int sig;
do {
sig = sys_sigtimedwait(&sigalarm_only, NULL, &timeout);
} while (sig == -1 && errno == EINTR);
assert(sig == kSignal);
// Disable timer, check saving of old timer value.
struct kernel_itimerval empty_itimer = {};
struct kernel_itimerval old_itimer;
empty_itimer.it_interval.tv_sec = 0;
empty_itimer.it_interval.tv_usec = 0;
empty_itimer.it_value = empty_itimer.it_interval;
assert(sys_setitimer(ITIMER_REAL, &empty_itimer, &old_itimer) == 0);
assert(kernel_timeval_eq(&old_itimer.it_interval, &new_itimer.it_interval));
return 0;
}

54
src/third_party/lss/tests/sigaction.c vendored Normal file
View File

@ -0,0 +1,54 @@
/* Copyright 2020 Google LLC
*
* 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 LLC nor the names of its
* 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 "test_skel.h"
void test_handler(int sig) {}
int main(int argc, char *argv[]) {
const size_t kSigsetSize = sizeof(struct kernel_sigset_t);
struct kernel_sigaction action = {};
// Invalid signal returns EINVAL.
assert(sys_rt_sigaction(SIGKILL, &action, NULL, kSigsetSize) == -1);
assert(errno == EINVAL);
// Set an action.
action.sa_handler_ = test_handler;
action.sa_flags = SA_SIGINFO;
assert(sys_sigemptyset(&action.sa_mask) == 0);
assert(sys_sigaddset(&action.sa_mask, SIGPIPE) == 0);
assert(sys_rt_sigaction(SIGSEGV, &action, NULL, kSigsetSize) == 0);
// Retrieve the action.
struct kernel_sigaction old_action = {};
assert(sys_rt_sigaction(SIGSEGV, NULL, &old_action, kSigsetSize) == 0);
assert(memcmp(&action, &old_action, sizeof(action)) == 0);
return 0;
}

View File

@ -0,0 +1,58 @@
/* Copyright 2019 Google LLC
*
* 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 LLC nor the names of its
* 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 "test_skel.h"
int main(int argc, char *argv[]) {
struct kernel_sigset_t sigset = {};
siginfo_t siginfo = {};
struct timespec timeout = {};
// Invalid timeouts.
timeout.tv_sec = -1;
assert(sys_sigtimedwait(&sigset, &siginfo, &timeout) == -1);
assert(errno == EINVAL);
// Expired timeouts.
timeout.tv_sec = 0;
assert(sys_sigtimedwait(&sigset, &siginfo, &timeout) == -1);
assert(errno == EAGAIN);
// Success.
const int kTestSignal = SIGCONT;
assert(sys_sigemptyset(&sigset) == 0);
assert(sys_sigaddset(&sigset, kTestSignal) == 0);
assert(sys_sigprocmask(SIG_BLOCK, &sigset, NULL) == 0);
assert(raise(kTestSignal) == 0);
assert(sys_sigtimedwait(&sigset, &siginfo, &timeout) == kTestSignal);
assert(siginfo.si_signo == kTestSignal);
return 0;
}

67
src/third_party/lss/tests/stat.c vendored Normal file
View File

@ -0,0 +1,67 @@
/* Copyright 2021 Google LLC
*
* 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 LLC nor the names of its
* 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 "test_skel.h"
int main(int argc, char *argv[]) {
int exit_status = 0;
// Get two unique paths to play with.
char foo[] = "tempfile.XXXXXX";
int fd_foo = mkstemp(foo);
assert(fd_foo != -1);
// Make sure it exists.
assert(access(foo, F_OK) == 0);
// Make sure sys_stat() and a libc stat() implementation return the same
// information.
struct stat libc_stat;
assert(stat(foo, &libc_stat) == 0);
struct kernel_stat raw_stat;
// We need to check our stat syscall for EOVERFLOW, as sometimes the integer
// types used in the stat structures are too small to fit the actual value.
// E.g. on some systems st_ino is 32-bit, but some filesystems have 64-bit
// inodes.
int rc = sys_stat(foo, &raw_stat);
if (rc < 0 && errno == EOVERFLOW) {
// Bail out since we had an overflow in the stat structure.
exit_status = SKIP_TEST_EXIT_STATUS;
goto cleanup;
}
assert(rc == 0);
assert(libc_stat.st_ino == raw_stat.st_ino);
cleanup:
sys_unlink(foo);
return exit_status;
}

89
src/third_party/lss/tests/test_skel.h vendored Normal file
View File

@ -0,0 +1,89 @@
/* Copyright 2018 Google LLC
*
* 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 LLC nor the names of its
* 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.
*/
/*
* Make sure it's defined before including anything else. A number of syscalls
* are GNU extensions and rely on being exported by glibc.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
/*
* Make sure the assert checks aren't removed as all the unittests are based
* on them.
*/
#undef NDEBUG
#include <assert.h>
#include <fcntl.h>
#include <sched.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/prctl.h>
#include <sys/stat.h>
#include <sys/vfs.h>
#include <sys/wait.h>
#include <unistd.h>
#include <linux/capability.h>
#include "linux_syscall_support.h"
#define SKIP_TEST_EXIT_STATUS 77
void assert_buffers_eq_len(const void *buf1, const void *buf2, size_t len) {
const uint8_t *u8_1 = (const uint8_t *)buf1;
const uint8_t *u8_2 = (const uint8_t *)buf2;
size_t i;
for (i = 0; i < len; ++i) {
if (u8_1[i] != u8_2[i])
printf("offset %zu: %02x != %02x\n", i, u8_1[i], u8_2[i]);
}
}
#define assert_buffers_eq(obj1, obj2) assert_buffers_eq_len(obj1, obj2, sizeof(*obj1))
// Returns true iff pointed timevals are equal.
static inline bool kernel_timeval_eq(const struct kernel_timeval* lhs,
const struct kernel_timeval* rhs) {
return (lhs->tv_sec == rhs->tv_sec) && (lhs->tv_usec == rhs->tv_usec);
}
// Returns true iff pointed itimervals are equal.
static inline bool kernel_itimerval_eq(const struct kernel_itimerval* lhs,
const struct kernel_itimerval* rhs) {
return kernel_timeval_eq(&lhs->it_interval, &rhs->it_interval) &&
kernel_timeval_eq(&lhs->it_value, &rhs->it_value);
}

48
src/third_party/lss/tests/unlink.c vendored Normal file
View File

@ -0,0 +1,48 @@
/* Copyright 2018 Google LLC
*
* 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 LLC nor the names of its
* 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 "test_skel.h"
int main(int argc, char *argv[]) {
// Get a unique path to play with.
char foo[] = "tempfile.XXXXXX";
int fd = mkstemp(foo);
assert(fd != -1);
// Make sure it exists.
assert(access(foo, F_OK) == 0);
// Then delete it.
assert(sys_unlink(foo) == 0);
// Make sure it's gone.
assert(access(foo, F_OK) != 0);
return 0;
}