1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright 2025 Hans Rosenfeld
14 */
15
16 /*
17 * Basic dprintf test. Print something into a pipe, and verify that we can
18 * read it back.
19 */
20
21 #include <sys/types.h>
22 #include <sys/wait.h>
23 #include <sys/fork.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <unistd.h>
28 #include <err.h>
29
30 static const char hello[] = "Hello ";
31 static const char world[] = "World!";
32
33 static void
check_len(const char * ident,ssize_t len,ssize_t exp_len)34 check_len(const char *ident, ssize_t len, ssize_t exp_len)
35 {
36 if (len == -1)
37 err(EXIT_FAILURE, "%s", ident);
38 if (len != exp_len)
39 errx(EXIT_FAILURE, "unexpected length from %s: %zd "
40 "(expected %zd)", ident, len, exp_len);
41 }
42
43 static void
check_buf(const char * buf,const char * exp,int len)44 check_buf(const char *buf, const char *exp, int len)
45 {
46 if (strncmp(buf, exp, len) != 0)
47 errx(EXIT_FAILURE, "unexpected buffer contents:\n"
48 "%s\nexpected:\n%s", buf, exp);
49 }
50
51 int
main(int argc,char ** argv)52 main(int argc, char **argv)
53 {
54 int ret = -1;
55 char buf[40] = { 0 };
56 int fd[2];
57 ssize_t len;
58 pid_t pid;
59
60 if (pipe(fd) == -1)
61 err(EXIT_FAILURE, "pipe(fd)");
62
63 pid = forkx(FORK_NOSIGCHLD | FORK_WAITPID);
64
65 switch (pid) {
66 case -1:
67 err(EXIT_FAILURE, "fork()");
68
69 case 0:
70 (void) close(fd[0]);
71
72 len = dprintf(fd[1], "%s", hello);
73 check_len("dprintf(hello)", len, strlen(hello));
74
75 len = dprintf(fd[1], "%s\n", world);
76 check_len("dprintf(world)", len, strlen(world) + 1);
77
78 len = dprintf(fd[1], "%sagain, %s\n", hello, world);
79 check_len("dprintf(hello, world)", len,
80 strlen(hello) + strlen(world) + 8);
81
82 return (0);
83
84 default:
85 (void) close(fd[1]);
86
87 if (waitpid(pid, &ret, 0) != pid)
88 err(EXIT_FAILURE, "waitpid()");
89
90 if (ret != 0)
91 errx(EXIT_FAILURE, "dprintf tests failed");
92
93 len = read(fd[0], buf, sizeof (buf));
94 check_len("read()", len,
95 2 * (strlen(hello) + strlen(world) + 1) + 7);
96 check_buf(buf, "Hello World!\nHello again, World!\n", len);
97 }
98
99 (void) printf("dprintf tests passed\n");
100 return (0);
101 }
102