Files
mirror_zfs/tests/zfs-tests/cmd/mkbusy.c
T

165 lines
3.1 KiB
C
Raw Normal View History

2025-01-04 11:04:27 +11:00
// SPDX-License-Identifier: CDDL-1.0
2015-07-01 15:23:09 -07:00
/*
* This file and its contents are supplied under the terms of the
* Common Development and Distribution License ("CDDL"), version 1.0.
* You may only use this file in accordance with the terms of version
* 1.0 of the CDDL.
*
* A full copy of the text of the CDDL should have accompanied this
* source. A copy of the CDDL is also available via the Internet at
* http://www.illumos.org/license/CDDL.
*/
/*
* Copyright (c) 2012 by Delphix. All rights reserved.
*/
/*
* Make a directory busy. If the argument is an existing file or directory,
* simply open it directly and pause. If not, verify that the parent directory
* exists, and create a new file in that directory.
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <string.h>
2015-07-01 15:23:09 -07:00
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
2021-06-05 14:18:37 +02:00
static __attribute__((noreturn)) void
2022-04-19 20:38:30 +02:00
usage(const char *progname)
2015-07-01 15:23:09 -07:00
{
(void) fprintf(stderr, "Usage: %s <dirname|filename>\n", progname);
exit(1);
}
static __attribute__((noreturn)) void
2022-04-19 20:38:30 +02:00
fail(const char *err)
2015-07-01 15:23:09 -07:00
{
perror(err);
2021-06-05 14:18:37 +02:00
exit(1);
2015-07-01 15:23:09 -07:00
}
static void
daemonize(void)
{
pid_t pid;
if ((pid = fork()) < 0) {
2021-06-05 14:18:37 +02:00
fail("fork");
2015-07-01 15:23:09 -07:00
} else if (pid != 0) {
(void) fprintf(stdout, "%ld\n", (long)pid);
exit(0);
}
(void) setsid();
(void) close(0);
(void) close(1);
(void) close(2);
}
static const char *
get_basename(const char *path)
{
const char *bn = strrchr(path, '/');
return (bn ? bn + 1 : path);
}
static ssize_t
get_dirnamelen(const char *path)
{
const char *end = strrchr(path, '/');
return (end ? end - path : -1);
}
2015-07-01 15:23:09 -07:00
int
main(int argc, char *argv[])
{
2021-06-05 14:18:37 +02:00
int c;
2015-07-01 15:23:09 -07:00
boolean_t isdir = B_FALSE;
struct stat sbuf;
char *fpath = NULL;
char *prog = argv[0];
2021-06-05 14:18:37 +02:00
while ((c = getopt(argc, argv, "")) != -1) {
2015-07-01 15:23:09 -07:00
switch (c) {
default:
usage(prog);
}
}
argc -= optind;
argv += optind;
if (argc != 1)
usage(prog);
2021-06-05 14:18:37 +02:00
if (stat(argv[0], &sbuf) != 0) {
char *arg;
const char *dname, *fname;
size_t arglen;
ssize_t dnamelen;
2015-07-01 15:23:09 -07:00
/*
* The argument supplied doesn't exist. Copy the path, and
2020-06-10 06:24:09 +02:00
* remove the trailing slash if present.
2015-07-01 15:23:09 -07:00
*/
if ((arg = strdup(argv[0])) == NULL)
2021-06-05 14:18:37 +02:00
fail("strdup");
2015-07-01 15:23:09 -07:00
arglen = strlen(arg);
if (arg[arglen - 1] == '/')
arg[arglen - 1] = '\0';
2021-06-05 14:18:37 +02:00
/* Get the directory and file names. */
fname = get_basename(arg);
2021-06-05 14:18:37 +02:00
dname = arg;
if ((dnamelen = get_dirnamelen(arg)) != -1)
2021-06-05 14:18:37 +02:00
arg[dnamelen] = '\0';
else
dname = ".";
2015-07-01 15:23:09 -07:00
/* The directory portion of the path must exist */
2021-06-05 14:18:37 +02:00
if (stat(dname, &sbuf) != 0 || !(sbuf.st_mode & S_IFDIR))
2015-07-01 15:23:09 -07:00
usage(prog);
2021-06-05 14:18:37 +02:00
if (asprintf(&fpath, "%s/%s", dname, fname) == -1)
fail("asprintf");
2015-07-01 15:23:09 -07:00
2021-06-05 14:18:37 +02:00
free(arg);
} else
switch (sbuf.st_mode & S_IFMT) {
case S_IFDIR:
isdir = B_TRUE;
2022-02-16 01:58:59 +09:00
zfs_fallthrough;
2021-06-05 14:18:37 +02:00
case S_IFLNK:
case S_IFCHR:
case S_IFBLK:
if ((fpath = strdup(argv[0])) == NULL)
fail("strdup");
break;
default:
usage(prog);
}
2015-07-01 15:23:09 -07:00
2021-06-05 14:18:37 +02:00
if (!isdir) {
if (open(fpath, O_CREAT | O_RDWR, 0600) < 0)
2021-06-05 14:18:37 +02:00
fail("open");
2015-07-01 15:23:09 -07:00
} else {
if (opendir(fpath) == NULL)
2021-06-05 14:18:37 +02:00
fail("opendir");
2015-07-01 15:23:09 -07:00
}
free(fpath);
2021-06-05 14:18:37 +02:00
daemonize();
2015-07-01 15:23:09 -07:00
(void) pause();
return (0);
}