xref: /illumos-gate/usr/src/test/util-tests/tests/cpmvln/mkobj.c (revision 6cf3cc9d1e40f89e90135a48f74f03f879fce639)
1*6cf3cc9dSRobert Mustacchi /*
2*6cf3cc9dSRobert Mustacchi  * This file and its contents are supplied under the terms of the
3*6cf3cc9dSRobert Mustacchi  * Common Development and Distribution License ("CDDL"), version 1.0.
4*6cf3cc9dSRobert Mustacchi  * You may only use this file in accordance with the terms of version
5*6cf3cc9dSRobert Mustacchi  * 1.0 of the CDDL.
6*6cf3cc9dSRobert Mustacchi  *
7*6cf3cc9dSRobert Mustacchi  * A full copy of the text of the CDDL should have accompanied this
8*6cf3cc9dSRobert Mustacchi  * source.  A copy of the CDDL is also available via the Internet at
9*6cf3cc9dSRobert Mustacchi  * http://www.illumos.org/license/CDDL.
10*6cf3cc9dSRobert Mustacchi  */
11*6cf3cc9dSRobert Mustacchi 
12*6cf3cc9dSRobert Mustacchi /*
13*6cf3cc9dSRobert Mustacchi  * Copyright 2024 Oxide Computer Company
14*6cf3cc9dSRobert Mustacchi  */
15*6cf3cc9dSRobert Mustacchi 
16*6cf3cc9dSRobert Mustacchi /*
17*6cf3cc9dSRobert Mustacchi  * This is a utility program for the various cp/mv/ln tests to create file
18*6cf3cc9dSRobert Mustacchi  * system objects which are not as simple with basic utilities. In particular we
19*6cf3cc9dSRobert Mustacchi  * support creating bound unix domain sockets, doors, and throw in a fifo for
20*6cf3cc9dSRobert Mustacchi  * good measure (though that's a bit easier).
21*6cf3cc9dSRobert Mustacchi  */
22*6cf3cc9dSRobert Mustacchi 
23*6cf3cc9dSRobert Mustacchi #include <err.h>
24*6cf3cc9dSRobert Mustacchi #include <sys/types.h>
25*6cf3cc9dSRobert Mustacchi #include <sys/stat.h>
26*6cf3cc9dSRobert Mustacchi #include <fcntl.h>
27*6cf3cc9dSRobert Mustacchi #include <stdlib.h>
28*6cf3cc9dSRobert Mustacchi #include <unistd.h>
29*6cf3cc9dSRobert Mustacchi #include <door.h>
30*6cf3cc9dSRobert Mustacchi #include <stropts.h>
31*6cf3cc9dSRobert Mustacchi #include <string.h>
32*6cf3cc9dSRobert Mustacchi #include <sys/socket.h>
33*6cf3cc9dSRobert Mustacchi 
34*6cf3cc9dSRobert Mustacchi static void
mkobj_server(void * cookie,char * argp,size_t size,door_desc_t * dp,uint_t ndesc)35*6cf3cc9dSRobert Mustacchi mkobj_server(void *cookie, char *argp, size_t size, door_desc_t *dp,
36*6cf3cc9dSRobert Mustacchi     uint_t ndesc)
37*6cf3cc9dSRobert Mustacchi {
38*6cf3cc9dSRobert Mustacchi 	(void) door_return(NULL, 0, NULL, 0);
39*6cf3cc9dSRobert Mustacchi }
40*6cf3cc9dSRobert Mustacchi 
41*6cf3cc9dSRobert Mustacchi int
main(int argc,char * argv[])42*6cf3cc9dSRobert Mustacchi main(int argc, char *argv[])
43*6cf3cc9dSRobert Mustacchi {
44*6cf3cc9dSRobert Mustacchi 	int c;
45*6cf3cc9dSRobert Mustacchi 	const char *door = NULL;
46*6cf3cc9dSRobert Mustacchi 	const char *fifo = NULL;
47*6cf3cc9dSRobert Mustacchi 	const char *uds = NULL;
48*6cf3cc9dSRobert Mustacchi 
49*6cf3cc9dSRobert Mustacchi 	while ((c = getopt(argc, argv, ":d:f:s:")) != -1) {
50*6cf3cc9dSRobert Mustacchi 		switch (c) {
51*6cf3cc9dSRobert Mustacchi 		case 'd':
52*6cf3cc9dSRobert Mustacchi 			door = optarg;
53*6cf3cc9dSRobert Mustacchi 			break;
54*6cf3cc9dSRobert Mustacchi 		case 'f':
55*6cf3cc9dSRobert Mustacchi 			fifo = optarg;
56*6cf3cc9dSRobert Mustacchi 			break;
57*6cf3cc9dSRobert Mustacchi 		case 's':
58*6cf3cc9dSRobert Mustacchi 			uds = optarg;
59*6cf3cc9dSRobert Mustacchi 			break;
60*6cf3cc9dSRobert Mustacchi 		case ':':
61*6cf3cc9dSRobert Mustacchi 			errx(EXIT_FAILURE, "option -%c requires an operand", c);
62*6cf3cc9dSRobert Mustacchi 		case '?':
63*6cf3cc9dSRobert Mustacchi 			(void) fprintf(stderr, "unknown option: -%c\n", c);
64*6cf3cc9dSRobert Mustacchi 			(void) fprintf(stderr, "mkobj [-d door] [-f fifo] "
65*6cf3cc9dSRobert Mustacchi 			    "[-s socket]\n");
66*6cf3cc9dSRobert Mustacchi 			exit(EXIT_FAILURE);
67*6cf3cc9dSRobert Mustacchi 		}
68*6cf3cc9dSRobert Mustacchi 	}
69*6cf3cc9dSRobert Mustacchi 
70*6cf3cc9dSRobert Mustacchi 	argv += optind;
71*6cf3cc9dSRobert Mustacchi 	argc -= optind;
72*6cf3cc9dSRobert Mustacchi 
73*6cf3cc9dSRobert Mustacchi 	if (argc != 0) {
74*6cf3cc9dSRobert Mustacchi 		errx(EXIT_FAILURE, "extraneous arguments starting with %s",
75*6cf3cc9dSRobert Mustacchi 		    argv[0]);
76*6cf3cc9dSRobert Mustacchi 	}
77*6cf3cc9dSRobert Mustacchi 
78*6cf3cc9dSRobert Mustacchi 	if (door == NULL && fifo == NULL && uds == NULL) {
79*6cf3cc9dSRobert Mustacchi 		errx(EXIT_FAILURE, "at least one of -d, -f and -s must be "
80*6cf3cc9dSRobert Mustacchi 		    "specified");
81*6cf3cc9dSRobert Mustacchi 	}
82*6cf3cc9dSRobert Mustacchi 
83*6cf3cc9dSRobert Mustacchi 	if (door != NULL) {
84*6cf3cc9dSRobert Mustacchi 		int fd;
85*6cf3cc9dSRobert Mustacchi 
86*6cf3cc9dSRobert Mustacchi 		if ((fd = open(door, O_CREAT | O_EXCL | O_RDWR, 0666)) < 0) {
87*6cf3cc9dSRobert Mustacchi 			err(EXIT_FAILURE, "failed to create file %s for door "
88*6cf3cc9dSRobert Mustacchi 			    "server attachment", door);
89*6cf3cc9dSRobert Mustacchi 		}
90*6cf3cc9dSRobert Mustacchi 
91*6cf3cc9dSRobert Mustacchi 		(void) close(fd);
92*6cf3cc9dSRobert Mustacchi 
93*6cf3cc9dSRobert Mustacchi 		if ((fd = door_create(mkobj_server, NULL, DOOR_REFUSE_DESC |
94*6cf3cc9dSRobert Mustacchi 		    DOOR_NO_CANCEL)) < 0) {
95*6cf3cc9dSRobert Mustacchi 			err(EXIT_FAILURE, "failed to create door server");
96*6cf3cc9dSRobert Mustacchi 		}
97*6cf3cc9dSRobert Mustacchi 
98*6cf3cc9dSRobert Mustacchi 		if (fattach(fd, door) != 0) {
99*6cf3cc9dSRobert Mustacchi 			err(EXIT_FAILURE, "failed to attach door to %s", door);
100*6cf3cc9dSRobert Mustacchi 		}
101*6cf3cc9dSRobert Mustacchi 	}
102*6cf3cc9dSRobert Mustacchi 
103*6cf3cc9dSRobert Mustacchi 	if (fifo != NULL) {
104*6cf3cc9dSRobert Mustacchi 		if (mkfifo(fifo, 0666) != 0) {
105*6cf3cc9dSRobert Mustacchi 			err(EXIT_FAILURE, "failed to make fifo %s", fifo);
106*6cf3cc9dSRobert Mustacchi 		}
107*6cf3cc9dSRobert Mustacchi 	}
108*6cf3cc9dSRobert Mustacchi 
109*6cf3cc9dSRobert Mustacchi 	if (uds != NULL) {
110*6cf3cc9dSRobert Mustacchi 		int fd;
111*6cf3cc9dSRobert Mustacchi 		struct sockaddr_un un;
112*6cf3cc9dSRobert Mustacchi 
113*6cf3cc9dSRobert Mustacchi 		if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
114*6cf3cc9dSRobert Mustacchi 			err(EXIT_FAILURE, "failed to create a unix domain "
115*6cf3cc9dSRobert Mustacchi 			    "socket");
116*6cf3cc9dSRobert Mustacchi 		}
117*6cf3cc9dSRobert Mustacchi 
118*6cf3cc9dSRobert Mustacchi 		(void) memset(&un, 0, sizeof (un));
119*6cf3cc9dSRobert Mustacchi 		un.sun_family = AF_UNIX;
120*6cf3cc9dSRobert Mustacchi 		if (strlcpy(un.sun_path, uds, sizeof (un.sun_path)) >=
121*6cf3cc9dSRobert Mustacchi 		    sizeof (un.sun_path)) {
122*6cf3cc9dSRobert Mustacchi 			errx(EXIT_FAILURE, "UDS path %s doesn't fit in "
123*6cf3cc9dSRobert Mustacchi 			    "sockaddr sun_path", uds);
124*6cf3cc9dSRobert Mustacchi 		}
125*6cf3cc9dSRobert Mustacchi 
126*6cf3cc9dSRobert Mustacchi 		if (bind(fd, (struct sockaddr *)&un, sizeof (un)) != 0) {
127*6cf3cc9dSRobert Mustacchi 			errx(EXIT_FAILURE, "failed to bind uds to %s", uds);
128*6cf3cc9dSRobert Mustacchi 		}
129*6cf3cc9dSRobert Mustacchi 	}
130*6cf3cc9dSRobert Mustacchi 
131*6cf3cc9dSRobert Mustacchi 	/*
132*6cf3cc9dSRobert Mustacchi 	 * Explicitly exit to ensure that we don't end up letting door threads
133*6cf3cc9dSRobert Mustacchi 	 * stick around.
134*6cf3cc9dSRobert Mustacchi 	 */
135*6cf3cc9dSRobert Mustacchi 	exit(EXIT_SUCCESS);
136*6cf3cc9dSRobert Mustacchi }
137