source: mainline/uspace/app/bdsh/cmds/modules/mkfile/mkfile.c@ 7e752b2

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 7e752b2 was 7e752b2, checked in by Martin Decky <martin@…>, 15 years ago
  • correct printf() formatting strings and corresponding arguments
  • minor cstyle changes and other small fixes
  • Property mode set to 100644
File size: 4.6 KB
RevLine 
[336d2faa]1/*
2 * Copyright (c) 2009 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29
30#include <stdio.h>
31#include <stdlib.h>
32#include <dirent.h>
33#include <fcntl.h>
34#include <sys/types.h>
35#include <sys/stat.h>
36#include <fcntl.h>
37#include <macros.h>
38#include <getopt.h>
39#include <stdarg.h>
[19f857a]40#include <str.h>
[336d2faa]41#include <ctype.h>
42
43#include "config.h"
44#include "errors.h"
45#include "util.h"
46#include "entry.h"
47#include "mkfile.h"
48#include "cmds.h"
49
50/** Number of bytes to write at a time */
51#define BUFFER_SIZE 16384
52
[a000878c]53static const char *cmdname = "mkfile";
[336d2faa]54
55static struct option const long_options[] = {
56 {"size", required_argument, 0, 's'},
57 {"help", no_argument, 0, 'h'},
58 {0, 0, 0, 0}
59};
60
61void help_cmd_mkfile(unsigned int level)
62{
63 if (level == HELP_SHORT) {
64 printf("`%s' creates a new zero-filled file\n", cmdname);
65 } else {
66 help_cmd_mkfile(HELP_SHORT);
67 printf(
68 "Usage: %s [options] <path>\n"
69 "Options:\n"
70 " -h, --help A short option summary\n"
71 " -s, --size sz Size of the file\n"
72 "\n"
73 "Size is a number followed by 'k', 'm' or 'g' for kB, MB, GB.\n"
74 "E.g. 100k, 2m, 1g.\n",
75 cmdname);
76 }
77
78 return;
79}
80
81/** Parse size specification.
82 *
83 * Size specification is in the form <decimal_number><unit> where
84 * <unit> is 'k', 'm' or 'g' for kB, MB, GB.
85 *
86 * @param str String containing the size specification.
87 * @return Non-negative size in bytes on success, -1 on failure.
88 */
89static ssize_t read_size(const char *str)
90{
91 ssize_t number, unit;
92 char *ep;
93
94 number = strtol(str, &ep, 10);
95 if (ep[0] == '\0')
96 return number;
97
98 if (ep[1] != '\0')
99 return -1;
100
101 switch (tolower(ep[0])) {
102 case 'k': unit = 1024; break;
103 case 'm': unit = 1024*1024; break;
104 case 'g': unit = 1024*1024*1024; break;
105 default: return -1;
106 }
107
108 return number * unit;
109}
110
111int cmd_mkfile(char **argv)
112{
113 unsigned int argc;
114 int c, opt_ind;
115 int fd;
116 ssize_t file_size;
117 ssize_t total_written;
118 ssize_t to_write, rc;
119 char *file_name;
120 void *buffer;
121
122 file_size = 0;
123
124 argc = cli_count_args(argv);
125
126 for (c = 0, optind = 0, opt_ind = 0; c != -1;) {
127 c = getopt_long(argc, argv, "pvhVfm:", long_options, &opt_ind);
128 switch (c) {
129 case 'h':
130 help_cmd_mkfile(HELP_LONG);
131 return CMD_SUCCESS;
132 case 's':
133 file_size = read_size(optarg);
134 if (file_size < 0) {
135 printf("%s: Invalid file size specification.\n",
136 cmdname);
137 return CMD_FAILURE;
138 }
139 break;
140 }
141 }
142
143 argc -= optind;
144
145 if (argc != 1) {
146 printf("%s: incorrect number of arguments. Try `%s --help'\n",
147 cmdname, cmdname);
148 return CMD_FAILURE;
149 }
150
151 file_name = argv[optind];
152
153 fd = open(file_name, O_CREAT | O_EXCL | O_WRONLY, 0666);
154 if (fd < 0) {
155 printf("%s: failed to create file %s.\n", cmdname, file_name);
156 return CMD_FAILURE;
157 }
158
159 buffer = calloc(BUFFER_SIZE, 1);
160 if (buffer == NULL) {
161 printf("%s: Error, out of memory.\n", cmdname);
162 return CMD_FAILURE;
163 }
164
165 total_written = 0;
166 while (total_written < file_size) {
167 to_write = min(file_size - total_written, BUFFER_SIZE);
168 rc = write(fd, buffer, to_write);
169 if (rc <= 0) {
[7e752b2]170 printf("%s: Error writing file (%zd).\n", cmdname, rc);
[336d2faa]171 close(fd);
172 return CMD_FAILURE;
173 }
174 total_written += rc;
175 }
176
177 rc = close(fd);
178 if (rc != 0) {
[7e752b2]179 printf("%s: Error writing file (%zd).\n", cmdname, rc);
[336d2faa]180 return CMD_FAILURE;
181 }
182
183 free(buffer);
184
185 return CMD_SUCCESS;
186}
Note: See TracBrowser for help on using the repository browser.