xref: /illumos-gate/usr/src/test/libc-tests/tests/dprintf.c (revision 34b5c75ae1f95c7b8ef561f3c7586e03a21f59e7)
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