2 * Copyright (c) 2009 Jiri Svoboda
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
33 #include <str_error.h>
49 /** Number of bytes to write at a time */
50 #define BUFFER_SIZE 16384
52 static const char *cmdname
= "mkfile";
54 static struct option
const long_options
[] = {
55 {"size", required_argument
, 0, 's'},
56 {"sparse", no_argument
, 0, 'p'},
57 {"help", no_argument
, 0, 'h'},
61 void help_cmd_mkfile(unsigned int level
)
63 if (level
== HELP_SHORT
) {
64 printf("`%s' creates a new zero-filled file\n", cmdname
);
66 help_cmd_mkfile(HELP_SHORT
);
68 "Usage: %s [options] <path>\n"
70 " -h, --help A short option summary\n"
71 " -s, --size sz Size of the file\n"
72 " -p, --sparse Create a sparse file\n"
74 "Size is a number followed by 'k', 'm' or 'g' for kB, MB, GB.\n"
75 "E.g. 100k, 2m, 1g.\n",
82 /** Parse size specification.
84 * Size specification is in the form <decimal_number><unit> where
85 * <unit> is 'k', 'm' or 'g' for kB, MB, GB.
87 * @param str String containing the size specification.
88 * @param rsize Place to store size in bytes
89 * @return EOK on success or an error code
91 static errno_t
read_size(const char *str
, size_t *rsize
)
96 number
= strtol(str
, &ep
, 10);
105 switch (tolower(ep
[0])) {
106 case 'k': unit
= 1024; break;
107 case 'm': unit
= 1024*1024; break;
108 case 'g': unit
= 1024*1024*1024; break;
109 default: return EINVAL
;
112 *rsize
= number
* unit
;
116 int cmd_mkfile(char **argv
)
122 size_t total_written
;
128 bool create_sparse
= false;
133 argc
= cli_count_args(argv
);
135 for (c
= 0, optreset
= 1, optind
= 0, opt_ind
= 0; c
!= -1;) {
136 c
= getopt_long(argc
, argv
, "ps:h", long_options
, &opt_ind
);
139 help_cmd_mkfile(HELP_LONG
);
142 create_sparse
= true;
145 rc
= read_size(optarg
, &file_size
);
147 printf("%s: Invalid file size specification.\n",
158 printf("%s: incorrect number of arguments. Try `%s --help'\n",
163 file_name
= argv
[optind
];
165 rc
= vfs_lookup_open(file_name
, WALK_REGULAR
| WALK_MUST_CREATE
, MODE_WRITE
, &fd
);
167 printf("%s: failed to create file %s.\n", cmdname
, file_name
);
171 if (create_sparse
&& file_size
> 0) {
172 const char byte
= 0x00;
175 rc
= vfs_write(fd
, &pos
, &byte
, sizeof(char), &nwritten
);
183 buffer
= calloc(BUFFER_SIZE
, 1);
184 if (buffer
== NULL
) {
185 printf("%s: Error, out of memory.\n", cmdname
);
190 while (total_written
< file_size
) {
191 to_write
= min(file_size
- total_written
, BUFFER_SIZE
);
192 rc
= vfs_write(fd
, &pos
, buffer
, to_write
, &nwritten
);
194 printf("%s: Error writing file (%s).\n", cmdname
, str_error(rc
));
199 total_written
+= nwritten
;
210 printf("%s: Error writing file (%s).\n", cmdname
, str_error(rc
));