]> git.proxmox.com Git - mirror_zfs.git/blame - tests/zfs-tests/cmd/mkbusy/mkbusy.c
Rename fallthrough to zfs_fallthrough
[mirror_zfs.git] / tests / zfs-tests / cmd / mkbusy / mkbusy.c
CommitLineData
6bb24f4d
BB
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 (c) 2012 by Delphix. All rights reserved.
14 */
15
16/*
17 * Make a directory busy. If the argument is an existing file or directory,
18 * simply open it directly and pause. If not, verify that the parent directory
19 * exists, and create a new file in that directory.
20 */
21
22#include <stdio.h>
23#include <sys/types.h>
24#include <sys/stat.h>
25#include <fcntl.h>
26#include <dirent.h>
27#include <strings.h>
28#include <stdlib.h>
29#include <unistd.h>
30#include <errno.h>
31#include <string.h>
32
90f1c3c9
AZ
33
34static __attribute__((noreturn)) void
6bb24f4d
BB
35usage(char *progname)
36{
37 (void) fprintf(stderr, "Usage: %s <dirname|filename>\n", progname);
38 exit(1);
39}
40
90f1c3c9
AZ
41static __attribute__((noreturn)) void
42fail(char *err)
6bb24f4d
BB
43{
44 perror(err);
90f1c3c9 45 exit(1);
6bb24f4d
BB
46}
47
48static void
49daemonize(void)
50{
51 pid_t pid;
52
53 if ((pid = fork()) < 0) {
90f1c3c9 54 fail("fork");
6bb24f4d
BB
55 } else if (pid != 0) {
56 (void) fprintf(stdout, "%ld\n", (long)pid);
57 exit(0);
58 }
59
60 (void) setsid();
61 (void) close(0);
62 (void) close(1);
63 (void) close(2);
64}
65
514498fe
BB
66
67static const char *
68get_basename(const char *path)
69{
70 const char *bn = strrchr(path, '/');
71 return (bn ? bn + 1 : path);
72}
73
74static ssize_t
75get_dirnamelen(const char *path)
76{
77 const char *end = strrchr(path, '/');
78 return (end ? end - path : -1);
79}
80
6bb24f4d
BB
81int
82main(int argc, char *argv[])
83{
90f1c3c9 84 int c;
6bb24f4d 85 boolean_t isdir = B_FALSE;
6bb24f4d
BB
86 struct stat sbuf;
87 char *fpath = NULL;
88 char *prog = argv[0];
89
90f1c3c9 90 while ((c = getopt(argc, argv, "")) != -1) {
6bb24f4d 91 switch (c) {
6bb24f4d
BB
92 default:
93 usage(prog);
94 }
95 }
96
97 argc -= optind;
98 argv += optind;
99
100 if (argc != 1)
101 usage(prog);
102
90f1c3c9
AZ
103 if (stat(argv[0], &sbuf) != 0) {
104 char *arg;
105 const char *dname, *fname;
106 size_t arglen;
107 ssize_t dnamelen;
6bb24f4d
BB
108
109 /*
110 * The argument supplied doesn't exist. Copy the path, and
dd4bc569 111 * remove the trailing slash if present.
6bb24f4d
BB
112 */
113 if ((arg = strdup(argv[0])) == NULL)
90f1c3c9 114 fail("strdup");
6bb24f4d
BB
115 arglen = strlen(arg);
116 if (arg[arglen - 1] == '/')
117 arg[arglen - 1] = '\0';
118
90f1c3c9 119 /* Get the directory and file names. */
514498fe 120 fname = get_basename(arg);
90f1c3c9 121 dname = arg;
514498fe 122 if ((dnamelen = get_dirnamelen(arg)) != -1)
90f1c3c9
AZ
123 arg[dnamelen] = '\0';
124 else
125 dname = ".";
6bb24f4d
BB
126
127 /* The directory portion of the path must exist */
90f1c3c9 128 if (stat(dname, &sbuf) != 0 || !(sbuf.st_mode & S_IFDIR))
6bb24f4d
BB
129 usage(prog);
130
90f1c3c9
AZ
131 if (asprintf(&fpath, "%s/%s", dname, fname) == -1)
132 fail("asprintf");
6bb24f4d 133
90f1c3c9
AZ
134 free(arg);
135 } else
136 switch (sbuf.st_mode & S_IFMT) {
137 case S_IFDIR:
138 isdir = B_TRUE;
9a70e97f 139 zfs_fallthrough;
90f1c3c9
AZ
140 case S_IFLNK:
141 case S_IFCHR:
142 case S_IFBLK:
143 if ((fpath = strdup(argv[0])) == NULL)
144 fail("strdup");
145 break;
146 default:
147 usage(prog);
148 }
6bb24f4d 149
90f1c3c9
AZ
150 if (!isdir) {
151 int fd;
6bb24f4d 152
90f1c3c9
AZ
153 if ((fd = open(fpath, O_CREAT | O_RDWR, 0600)) < 0)
154 fail("open");
6bb24f4d
BB
155 } else {
156 DIR *dp;
157
158 if ((dp = opendir(fpath)) == NULL)
90f1c3c9 159 fail("opendir");
6bb24f4d
BB
160 }
161 free(fpath);
162
90f1c3c9 163 daemonize();
6bb24f4d
BB
164 (void) pause();
165
6bb24f4d
BB
166 return (0);
167}