summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tools/testing/selftests/logger/.gitignore1
-rw-r--r--tools/testing/selftests/logger/Makefile24
-rw-r--r--tools/testing/selftests/logger/logger.c155
3 files changed, 180 insertions, 0 deletions
diff --git a/tools/testing/selftests/logger/.gitignore b/tools/testing/selftests/logger/.gitignore
new file mode 100644
index 000000000000..b1e5ec6fe6b1
--- /dev/null
+++ b/tools/testing/selftests/logger/.gitignore
@@ -0,0 +1 @@
+logger-test
diff --git a/tools/testing/selftests/logger/Makefile b/tools/testing/selftests/logger/Makefile
new file mode 100644
index 000000000000..02a9019108d8
--- /dev/null
+++ b/tools/testing/selftests/logger/Makefile
@@ -0,0 +1,24 @@
+CFLAGS += -I../../../../usr/include/
+CFLAGS += -std=gnu99
+CFLAGS += -D_GNU_SOURCE
+LDFLAGS = -pthread
+
+.PHONY: all clean
+
+include ../lib.mk
+
+TEST_CUSTOM_PROGS := $(OUTPUT)/logger-test
+all: $(TEST_CUSTOM_PROGS)
+
+OBJS = \
+ logger.o
+
+OBJS := $(patsubst %,$(OUTPUT)/%,$(OBJS))
+
+$(TEST_CUSTOM_PROGS): $(OBJS)
+ $(CC) -o $(TEST_CUSTOM_PROGS) $(OBJS) $(LDFLAGS)
+
+$(OBJS): $(OUTPUT)/%.o: %.c
+ $(CC) -c $^ -o $@ $(CFLAGS)
+
+EXTRA_CLEAN := $(TEST_CUSTOM_PROGS) $(OBJS)
diff --git a/tools/testing/selftests/logger/logger.c b/tools/testing/selftests/logger/logger.c
new file mode 100644
index 000000000000..0446e796fa35
--- /dev/null
+++ b/tools/testing/selftests/logger/logger.c
@@ -0,0 +1,155 @@
+#include <errno.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <linux/const.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#define LOGGER_SET_VERSION 44550
+#define LOGGER_SET_TAG 44551
+#define LOGGER_SET_PRIO 44552
+
+#define handle_error_en(en, msg) \
+ do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
+
+#define BIT(nr) ((1UL) << (nr))
+
+void *tstart(void *arg)
+{
+ int *fd = arg;
+ write(*fd, "child thread msg #1\nchild thread msg #2", 39);
+ return 0;
+}
+
+int main(int ac, char *av[]) {
+
+ char *device = "/dev/log_main";
+ char *msg = "The Foo";
+ char *tag = "stdio";
+ int c, fd, s;
+ pid_t child;
+ pthread_t tid;
+ struct iovec vec[3];
+ unsigned char prio = 4;
+ unsigned long test_mask = ~0UL;
+
+ while (1) {
+ static struct option long_options[] = {
+ {"priority", required_argument, 0, 'p'},
+ {"tag", required_argument, 0, 't'},
+ {"test-mask", required_argument, 0, 'm'},
+ {"device", required_argument, 0, 'd'},
+ {0, 0, 0, 0}
+ };
+
+ c = getopt_long(ac, av, "p:t:m:d:", long_options, NULL);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'p':
+ prio = (unsigned char) strtol(optarg, NULL, 10);
+ break;
+ case 't':
+ tag = strdup(optarg);
+ break;
+ case 'm':
+ test_mask = (unsigned char) strtol(optarg, NULL, 16);
+ break;
+ case 'd':
+ device = strdup(optarg);
+ break;
+ default:
+ exit(1);
+ }
+ }
+
+ setlinebuf(stdout);
+ fd = open(device, O_WRONLY);
+
+ if (ac >= 2) {
+ }
+
+ if (ac == 3) {
+ }
+
+ if (test_mask & BIT(0)) {
+ vec[0].iov_base = &prio;
+ vec[0].iov_len = 1;
+ vec[1].iov_base = tag;
+ vec[1].iov_len = strlen(tag) + 1;
+ vec[2].iov_base = msg;
+ vec[2].iov_len = strlen(msg) + 1;
+
+ writev(fd, vec, 3);
+ if (test_mask & BIT(1)) {
+ msg = "line #1\nline #2";
+ vec[2].iov_base = msg;
+ vec[2].iov_len = strlen(msg) + 1;
+
+ writev(fd, vec, 3);
+ }
+ }
+
+ ioctl(fd, LOGGER_SET_PRIO, prio);
+ ioctl(fd, LOGGER_SET_TAG, "\006\000\000\000stdio");
+
+ if (test_mask & BIT(2)) {
+
+ write(fd, "The Foo From STDIO\n", 19);
+
+ write(fd, "LINE #1\nLINE #2", 15);
+ write(fd, " CONTINUED\nONCE", 15);
+ write(fd, " AGAIN\n", 7);
+ }
+
+ if (test_mask & BIT(3)) {
+ msg = malloc(8000);
+ if (!msg)
+ return 1;
+
+ for (int i = 0; i < 8000; i++)
+ msg[i] = ' ' + (i % 96);
+ msg[7999] = '\n';
+ write(fd, msg, 8000);
+ }
+
+ if (test_mask & BIT(4)) {
+ child = fork();
+ if (child < 0) {
+ return -1;
+ } else if (child == 0) {
+ sleep(1);
+ printf("child: %d\n", getpid());
+ write(fd, "child 1\n", 8);
+ sleep(1);
+ write(fd, "child 2\n", 8);
+ close(fd);
+ return 0;
+ }
+ write(fd, "PARENT\n", 7);
+ printf("PARENT: %d\n", getpid());
+ wait(&s);
+ }
+
+ if (test_mask & BIT(5)) {
+ s = pthread_create(&tid, NULL, &tstart, &fd);
+ if (s != 0)
+ handle_error_en(s, "pthread_create");
+ sleep(1);
+ write(fd, "PARENT THREAD\n", 14);
+
+ s = pthread_join(tid, NULL);
+ if (s != 0)
+ handle_error_en(s, "pthread_join");
+ }
+
+ return 0;
+}