Path: blob/main/sys/contrib/openzfs/tests/zfs-tests/cmd/mkfile.c
48529 views
// SPDX-License-Identifier: CDDL-1.01/*2* CDDL HEADER START3*4* The contents of this file are subject to the terms of the5* Common Development and Distribution License, Version 1.0 only6* (the "License"). You may not use this file except in compliance7* with the License.8*9* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE10* or https://opensource.org/licenses/CDDL-1.0.11* See the License for the specific language governing permissions12* and limitations under the License.13*14* When distributing Covered Code, include this CDDL HEADER in each15* file and include the License file at usr/src/OPENSOLARIS.LICENSE.16* If applicable, add the following below this CDDL HEADER, with the17* fields enclosed by brackets "[]" replaced with your own identifying18* information: Portions Copyright [yyyy] [name of copyright owner]19*20* CDDL HEADER END21*/2223/*24* Copyright 2005 Sun Microsystems, Inc. All rights reserved.25* Use is subject to license terms.26*/2728#include <stdio.h>29#include <ctype.h>30#include <unistd.h>31#include <sys/stat.h>32#include <fcntl.h>33#include <stdlib.h>34#include <string.h>35#include <libintl.h>36#include <errno.h>37#include <sys/stdtypes.h>38#include <sys/sysmacros.h>3940#define BLOCKSIZE 512 /* bytes */41#define KILOBYTE 102442#define MEGABYTE (KILOBYTE * KILOBYTE)43#define GIGABYTE (KILOBYTE * MEGABYTE)4445#define FILE_MODE (S_ISVTX + S_IRUSR + S_IWUSR)4647static __attribute__((noreturn)) void48usage(void)49{50(void) fprintf(stderr, gettext(51"Usage: mkfile [-nv] <size>[g|k|b|m] <name1> [<name2>] ...\n"));52exit(1);53}5455int56main(int argc, char **argv)57{58char *opts;59off_t size;60size_t len;61size_t mult = 1;62char *buf = NULL;63size_t bufsz = 0;64int errors = 0;65int i;66int verbose = 0; /* option variable */67int nobytes = 0; /* option variable */68int saverr;6970if (argc == 1)71usage();7273while (argv[1] && argv[1][0] == '-') {74opts = &argv[1][0];75while (*(++opts)) {76switch (*opts) {77case 'v':78verbose++;79break;80case 'n':81nobytes++;82break;83default:84usage();85}86}87argc--;88argv++;89}90if (argc < 3)91usage();9293len = strlen(argv[1]);94if (len && isalpha(argv[1][len-1])) {95switch (argv[1][len-1]) {96case 'k':97case 'K':98mult = KILOBYTE;99break;100case 'b':101case 'B':102mult = BLOCKSIZE;103break;104case 'm':105case 'M':106mult = MEGABYTE;107break;108case 'g':109case 'G':110mult = GIGABYTE;111break;112default:113(void) fprintf(stderr,114gettext("unknown size %s\n"), argv[1]);115usage();116}117118for (i = 0; i <= (len-2); i++) {119if (!isdigit(argv[1][i])) {120(void) fprintf(stderr,121gettext("unknown size %s\n"), argv[1]);122usage();123}124}125argv[1][len-1] = '\0';126}127size = ((off_t)atoll(argv[1]) * (off_t)mult);128129argv++;130argc--;131132while (argc > 1) {133int fd;134135if (verbose)136(void) fprintf(stdout, gettext("%s %lld bytes\n"),137argv[1], (offset_t)size);138fd = open(argv[1], O_CREAT|O_TRUNC|O_RDWR, FILE_MODE);139if (fd < 0) {140saverr = errno;141(void) fprintf(stderr,142gettext("Could not open %s: %s\n"),143argv[1], strerror(saverr));144errors++;145argv++;146argc--;147continue;148} else if (fchown(fd, getuid(), getgid()) < 0) {149saverr = errno;150(void) fprintf(stderr, gettext(151"Could not set owner/group of %s: %s\n"),152argv[1], strerror(saverr));153(void) close(fd);154errors++;155argv++;156argc--;157continue;158} else if (lseek(fd, (off_t)size-1, SEEK_SET) < 0) {159saverr = errno;160(void) fprintf(stderr, gettext(161"Could not seek to offset %ld in %s: %s\n"),162(unsigned long)size-1, argv[1], strerror(saverr));163(void) close(fd);164errors++;165argv++;166argc--;167continue;168} else if (write(fd, "", 1) != 1) {169saverr = errno;170(void) fprintf(stderr, gettext(171"Could not set length of %s: %s\n"),172argv[1], strerror(saverr));173(void) close(fd);174errors++;175argv++;176argc--;177continue;178}179180if (!nobytes) {181off_t written = 0;182struct stat64 st;183184if (lseek(fd, (off_t)0, SEEK_SET) < 0) {185saverr = errno;186(void) fprintf(stderr, gettext(187"Could not seek to beginning of %s: %s\n"),188argv[1], strerror(saverr));189(void) close(fd);190errors++;191argv++;192argc--;193continue;194}195if (fstat64(fd, &st) < 0) {196saverr = errno;197(void) fprintf(stderr, gettext(198"Could not fstat64 %s: %s\n"),199argv[1], strerror(saverr));200(void) close(fd);201errors++;202argv++;203argc--;204continue;205}206if (bufsz != st.st_blksize) {207if (buf)208free(buf);209bufsz = (size_t)st.st_blksize;210buf = calloc(1, bufsz);211if (buf == NULL) {212(void) fprintf(stderr, gettext(213"Could not allocate buffer of"214" size %d\n"), (int)bufsz);215(void) close(fd);216bufsz = 0;217errors++;218argv++;219argc--;220continue;221}222}223while (written < size) {224ssize_t result;225size_t bytes = (size_t)MIN(bufsz, size-written);226227if ((result = write(fd, buf, bytes)) !=228(ssize_t)bytes) {229saverr = errno;230if (result < 0)231result = 0;232written += result;233(void) fprintf(stderr, gettext(234"%s: initialized %lu of %lu bytes: %s\n"),235argv[1], (unsigned long)written,236(unsigned long)size,237strerror(saverr));238errors++;239break;240}241written += bytes;242}243244/*245* A write(2) call in the above loop failed so246* close out this file and go on (error was247* already incremented when the write(2) failed).248*/249if (written < size) {250(void) close(fd);251argv++;252argc--;253continue;254}255}256if (close(fd) < 0) {257saverr = errno;258(void) fprintf(stderr, gettext(259"Error encountered when closing %s: %s\n"),260argv[1], strerror(saverr));261errors++;262argv++;263argc--;264continue;265}266267/*268* Only set the modes (including the sticky bit) if we269* had no problems. It is not an error for the chmod(2)270* to fail, but do issue a warning.271*/272if (chmod(argv[1], FILE_MODE) < 0)273(void) fprintf(stderr, gettext(274"warning: couldn't set mode to %#o\n"), FILE_MODE);275276argv++;277argc--;278}279280if (buf)281free(buf);282283return (errors);284}285286287