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