HelenOS sources
This source file includes following definitions.
- help_cmd_mkfile
- read_size
- cmd_mkfile
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <str_error.h>
#include <dirent.h>
#include <macros.h>
#include <getopt.h>
#include <stdarg.h>
#include <str.h>
#include <ctype.h>
#include <vfs/vfs.h>
#include "config.h"
#include "errors.h"
#include "util.h"
#include "entry.h"
#include "mkfile.h"
#include "cmds.h"
#define BUFFER_SIZE 16384
static const char *cmdname = "mkfile";
static struct option const long_options[] = {
{ "size", required_argument, 0, 's' },
{ "sparse", no_argument, 0, 'p' },
{ "help", no_argument, 0, 'h' },
{ 0, 0, 0, 0 }
};
void help_cmd_mkfile(unsigned int level)
{
if (level == HELP_SHORT) {
printf("`%s' creates a new zero-filled file\n", cmdname);
} else {
help_cmd_mkfile(HELP_SHORT);
printf(
"Usage: %s [options] <path>\n"
"Options:\n"
" -h, --help A short option summary\n"
" -s, --size sz Size of the file\n"
" -p, --sparse Create a sparse file\n"
"\n"
"Size is a number followed by 'k', 'm' or 'g' for kB, MB, GB.\n"
"E.g. 100k, 2m, 1g.\n",
cmdname);
}
return;
}
static errno_t read_size(const char *str, size_t *rsize)
{
size_t number, unit;
char *ep;
number = strtol(str, &ep, 10);
if (ep[0] == '\0') {
*rsize = number;
return EOK;
}
if (ep[1] != '\0')
return EINVAL;
switch (tolower(ep[0])) {
case 'k':
unit = 1024;
break;
case 'm':
unit = 1024 * 1024;
break;
case 'g':
unit = 1024 * 1024 * 1024;
break;
default:
return EINVAL;
}
*rsize = number * unit;
return EOK;
}
int cmd_mkfile(char **argv)
{
unsigned int argc;
int c, opt_ind;
int fd;
size_t file_size;
size_t total_written;
size_t to_write;
size_t nwritten;
errno_t rc;
char *file_name;
void *buffer;
bool create_sparse = false;
aoff64_t pos = 0;
file_size = 0;
argc = cli_count_args(argv);
c = 0;
optreset = 1;
optind = 0;
opt_ind = 0;
while (c != -1) {
c = getopt_long(argc, argv, "ps:h", long_options, &opt_ind);
switch (c) {
case 'h':
help_cmd_mkfile(HELP_LONG);
return CMD_SUCCESS;
case 'p':
create_sparse = true;
break;
case 's':
rc = read_size(optarg, &file_size);
if (rc != EOK) {
printf("%s: Invalid file size specification.\n",
cmdname);
return CMD_FAILURE;
}
break;
}
}
argc -= optind;
if (argc != 1) {
printf("%s: incorrect number of arguments. Try `%s --help'\n",
cmdname, cmdname);
return CMD_FAILURE;
}
file_name = argv[optind];
rc = vfs_lookup_open(file_name, WALK_REGULAR | WALK_MUST_CREATE, MODE_WRITE, &fd);
if (rc != EOK) {
printf("%s: failed to create file %s.\n", cmdname, file_name);
return CMD_FAILURE;
}
if (create_sparse && file_size > 0) {
const char byte = 0x00;
pos = file_size - 1;
rc = vfs_write(fd, &pos, &byte, sizeof(char), &nwritten);
if (rc != EOK) {
vfs_put(fd);
goto error;
}
return CMD_SUCCESS;
}
buffer = calloc(BUFFER_SIZE, 1);
if (buffer == NULL) {
printf("%s: Error, out of memory.\n", cmdname);
return CMD_FAILURE;
}
total_written = 0;
while (total_written < file_size) {
to_write = min(file_size - total_written, BUFFER_SIZE);
rc = vfs_write(fd, &pos, buffer, to_write, &nwritten);
if (rc != EOK) {
printf("%s: Error writing file (%s).\n", cmdname, str_error(rc));
vfs_put(fd);
free(buffer);
return CMD_FAILURE;
}
total_written += nwritten;
}
free(buffer);
rc = vfs_put(fd);
if (rc != EOK)
goto error;
return CMD_SUCCESS;
error:
printf("%s: Error writing file (%s).\n", cmdname, str_error(rc));
return CMD_FAILURE;
}
HelenOS homepage, sources at GitHub