From 30012351f6cadc25bf800c86f1431eade4ee0af5 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Fri, 1 Feb 2019 00:00:08 -0500 Subject: tests: New utility for making and testing socket files --- .gitignore | 1 + Makefile | 4 +- tests.sh | 22 +++---- tests/mksock.c | 131 +++++++++++++++++++++++++++++++++++++ tests/test_color.out | 1 + tests/test_color_ext.out | 1 + tests/test_color_ext0.out | 1 + tests/test_color_mh.out | 1 + tests/test_color_mh0.out | 1 + tests/test_color_mi.out | 1 + tests/test_color_missing_colon.out | 1 + tests/test_color_or.out | 1 + tests/test_color_or0_mi.out | 1 + tests/test_color_or_mi.out | 1 + tests/test_color_or_mi0.out | 1 + 15 files changed, 156 insertions(+), 13 deletions(-) create mode 100644 tests/mksock.c diff --git a/.gitignore b/.gitignore index b251086..99776af 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ *.o *.d /bfs +/tests/mksock diff --git a/Makefile b/Makefile index 2349727..c1249fa 100644 --- a/Makefile +++ b/Makefile @@ -94,7 +94,7 @@ tests/mksock: tests/mksock.o %.o: %.c $(CC) $(ALL_CFLAGS) -c $< -o $@ -check: all +check: all tests/mksock ./tests.sh distcheck: @@ -107,7 +107,7 @@ endif +$(MAKE) -Bs check clean: - $(RM) bfs *.o *.d + $(RM) bfs *.[od] tests/mksock tests/*.[od] install: $(MKDIR) $(DESTDIR)$(PREFIX)/bin diff --git a/tests.sh b/tests.sh index 302a4c2..57b19de 100755 --- a/tests.sh +++ b/tests.sh @@ -22,6 +22,16 @@ umask 022 export LC_ALL=C export TZ=UTC +function _realpath() { + ( + cd "${1%/*}" + echo "$PWD/${1##*/}" + ) +} + +BFS="$(_realpath ./bfs)" +TESTS="$(_realpath ./tests)" + # The temporary directory that will hold our test data TMP="$(mktemp -d "${TMPDIR:-/tmp}"/bfs.XXXXXXXXXX)" chown "$(id -u):$(id -g)" "$TMP" @@ -177,7 +187,7 @@ function make_rainbow() { # TODO: block # TODO: chardev ln -s nowhere "$1/broken" - # TODO: socket + "$TESTS/mksock" "$1/socket" touchp "$1"/s{u,g,ug}id chmod u+s "$1"/su{,g}id chmod g+s "$1"/s{u,}gid @@ -195,16 +205,6 @@ function make_scratch() { } make_scratch "$TMP/scratch" -function _realpath() { - ( - cd "${1%/*}" - echo "$PWD/${1##*/}" - ) -} - -BFS="$(_realpath ./bfs)" -TESTS="$(_realpath ./tests)" - posix_tests=( # General parsing test_basic diff --git a/tests/mksock.c b/tests/mksock.c new file mode 100644 index 0000000..a996d58 --- /dev/null +++ b/tests/mksock.c @@ -0,0 +1,131 @@ +/**************************************************************************** + * bfs * + * Copyright (C) 2019 Tavian Barnes * + * * + * Permission to use, copy, modify, and/or distribute this software for any * + * purpose with or without fee is hereby granted. * + * * + * 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. * + ****************************************************************************/ + +/** + * There's no standard Unix utility that creates a socket file, so this small + * program does the job. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * Print an error message. + */ +static void errmsg(const char *cmd, const char *path) { + fprintf(stderr, "%s: '%s': %s.\n", cmd, path, strerror(errno)); +} + +/** + * struct sockaddr_un::sun_path is very short, so we chdir() into the target + * directory before creating sockets in case the full path is too long but the + * file name is not. + */ +static int chdir_parent(const char *path) { + char *copy = strdup(path); + if (!copy) { + return -1; + } + const char *dir = dirname(copy); + + int ret = chdir(dir); + + int error = errno; + free(copy); + errno = error; + + return ret; +} + +/** + * Initialize a struct sockaddr_un with the right filename. + */ +static int init_sun(struct sockaddr_un *sock, const char *path) { + size_t len = strlen(path); + if (len == 0 || path[len - 1] == '/') { + errno = ENOENT; + return -1; + } + + char *copy = strdup(path); + if (!copy) { + return -1; + } + const char *base = basename(copy); + + len = strlen(base); + if (len >= sizeof(sock->sun_path)) { + free(copy); + errno = ENAMETOOLONG; + return -1; + } + + sock->sun_family = AF_UNIX; + memcpy(sock->sun_path, base, len + 1); + free(copy); + return 0; +} + +int main(int argc, char *argv[]) { + const char *cmd = argc > 0 ? argv[0] : "mksock"; + + if (argc != 2) { + fprintf(stderr, "Usage: %s NAME\n", cmd); + return EXIT_FAILURE; + } + + const char *path = argv[1]; + + if (chdir_parent(path) != 0) { + errmsg(cmd, path); + return EXIT_FAILURE; + } + + struct sockaddr_un sock; + if (init_sun(&sock, path) != 0) { + errmsg(cmd, path); + return EXIT_FAILURE; + } + + int fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (fd < 0) { + errmsg(cmd, path); + return EXIT_FAILURE; + } + + int ret = EXIT_SUCCESS; + + if (bind(fd, (struct sockaddr *)&sock, sizeof(sock)) != 0) { + errmsg(cmd, path); + ret = EXIT_FAILURE; + } + + if (close(fd) != 0) { + errmsg(cmd, path); + ret = EXIT_FAILURE; + } + + return ret; +} diff --git a/tests/test_color.out b/tests/test_color.out index e267da8..40e09b4 100644 --- a/tests/test_color.out +++ b/tests/test_color.out @@ -1,5 +1,6 @@ rainbow rainbow/exec.sh +rainbow/socket rainbow/link.txt rainbow/sticky_ow rainbow/sgid diff --git a/tests/test_color_ext.out b/tests/test_color_ext.out index d2e2a70..f8c4d28 100644 --- a/tests/test_color_ext.out +++ b/tests/test_color_ext.out @@ -1,5 +1,6 @@ rainbow rainbow/exec.sh +rainbow/socket rainbow/link.txt rainbow/file.txt rainbow/sticky_ow diff --git a/tests/test_color_ext0.out b/tests/test_color_ext0.out index 3bc8dc1..8710fc8 100644 --- a/tests/test_color_ext0.out +++ b/tests/test_color_ext0.out @@ -1,6 +1,7 @@ rainbow rainbow/file.txt rainbow/exec.sh +rainbow/socket rainbow/link.txt rainbow/sticky_ow rainbow/sgid diff --git a/tests/test_color_mh.out b/tests/test_color_mh.out index 600451e..32e2b95 100644 --- a/tests/test_color_mh.out +++ b/tests/test_color_mh.out @@ -1,5 +1,6 @@ rainbow rainbow/exec.sh +rainbow/socket rainbow/link.txt rainbow/mh1 rainbow/mh2 diff --git a/tests/test_color_mh0.out b/tests/test_color_mh0.out index e267da8..40e09b4 100644 --- a/tests/test_color_mh0.out +++ b/tests/test_color_mh0.out @@ -1,5 +1,6 @@ rainbow rainbow/exec.sh +rainbow/socket rainbow/link.txt rainbow/sticky_ow rainbow/sgid diff --git a/tests/test_color_mi.out b/tests/test_color_mi.out index e267da8..40e09b4 100644 --- a/tests/test_color_mi.out +++ b/tests/test_color_mi.out @@ -1,5 +1,6 @@ rainbow rainbow/exec.sh +rainbow/socket rainbow/link.txt rainbow/sticky_ow rainbow/sgid diff --git a/tests/test_color_missing_colon.out b/tests/test_color_missing_colon.out index d2e2a70..f8c4d28 100644 --- a/tests/test_color_missing_colon.out +++ b/tests/test_color_missing_colon.out @@ -1,5 +1,6 @@ rainbow rainbow/exec.sh +rainbow/socket rainbow/link.txt rainbow/file.txt rainbow/sticky_ow diff --git a/tests/test_color_or.out b/tests/test_color_or.out index 6e94bc6..e132546 100644 --- a/tests/test_color_or.out +++ b/tests/test_color_or.out @@ -1,5 +1,6 @@ rainbow rainbow/exec.sh +rainbow/socket rainbow/link.txt rainbow/broken rainbow/sticky_ow diff --git a/tests/test_color_or0_mi.out b/tests/test_color_or0_mi.out index cafa798..8b92ded 100644 --- a/tests/test_color_or0_mi.out +++ b/tests/test_color_or0_mi.out @@ -1,5 +1,6 @@ rainbow rainbow/exec.sh +rainbow/socket rainbow/broken rainbow/link.txt rainbow/sticky_ow diff --git a/tests/test_color_or_mi.out b/tests/test_color_or_mi.out index 7e57688..8a095a8 100644 --- a/tests/test_color_or_mi.out +++ b/tests/test_color_or_mi.out @@ -1,6 +1,7 @@ rainbow rainbow/broken rainbow/exec.sh +rainbow/socket rainbow/link.txt rainbow/sticky_ow rainbow/sgid diff --git a/tests/test_color_or_mi0.out b/tests/test_color_or_mi0.out index 7e57688..8a095a8 100644 --- a/tests/test_color_or_mi0.out +++ b/tests/test_color_or_mi0.out @@ -1,6 +1,7 @@ rainbow rainbow/broken rainbow/exec.sh +rainbow/socket rainbow/link.txt rainbow/sticky_ow rainbow/sgid -- cgit v1.2.3