python/guestfs-py.c
python/guestfs.pyc
regressions/test1.img
+regressions/test.out
ruby/bindtests.rb
ruby/ext/guestfs/extconf.h
ruby/ext/guestfs/_guestfs.c
arpa_inet
c-ctype
closeout
+full-write
gitlog-to-changelog
gnu-make
gnumakefile
vasprintf
vc-list-files
warnings
+xstrtol
+xstrtoll
'
$gnulib_tool \
command "/bin/echo 'foo bar'"
command "/bin/echo \'foo\'"
+=head1 NUMBERS
+
+Commands which take integers as parameters use the C convention which
+is to use C<0> to prefix an octal number or C<0x> to prefix a
+hexadecimal number. For example:
+
+ 1234 decimal number 1234
+ 02322 octal number, equivalent to decimal 1234
+ 0x4d2 hexadecimal number, equivalent to decimal 1234
+
+When using the C<chmod> command, you almost always want to specify an
+octal number for the mode, and you must prefix it with C<0> (unlike
+the Unix L<chmod(1)> program):
+
+ chmod 0777 /public # OK
+ chmod 777 /public # WRONG! This is mode 777 decimal = 01411 octal.
+
+Commands that return numbers currently always print them in decimal.
+
=head1 WILDCARDS AND GLOBBING
Neither guestfish nor the underlying guestfs API performs
/yield.m4
/fcntl-o.m4
/warn-on-use.m4
+/getopt.m4
+/stat.m4
+/symlink.m4
+/time_h.m4
+/xstrtol.m4
+/safe-read.m4
+/safe-write.m4
+/ssize_t.m4
+/write.m4
+/strtol.m4
+/strtoll.m4
+/strtoul.m4
+/strtoull.m4
TESTS = \
rhbz503169c10.sh \
rhbz503169c13.sh \
+ rhbz557655.sh \
test-cancellation-download-librarycancels.sh \
test-cancellation-upload-daemoncancels.sh \
test-find0.sh \
EXTRA_DIST = \
$(FAILING_TESTS) \
$(SKIPPED_TESTS) \
- $(TESTS)
+ $(TESTS) \
+ rhbz557655-expected.out
--- /dev/null
+0
+16
+8
+-1073741824
+1073741823
+set-memsize: memsize: integer out of range
+set-memsize: memsize: integer out of range
+set-memsize: memsize: integer out of range
+set-memsize: memsize: integer out of range
+set-memsize: memsize: invalid integer parameter (xstrtol returned 4)
+set-memsize: memsize: invalid integer parameter (xstrtol returned 2)
+set-memsize: memsize: invalid integer parameter (xstrtol returned 2)
+set-memsize: memsize: invalid integer parameter (xstrtol returned 2)
+1234
+1234
+1234
+libguestfs: error: truncate_size: ftruncate: /test: File too large
+truncate-size: size: invalid integer parameter (xstrtoll returned 1)
+truncate-size: size: invalid integer parameter (xstrtoll returned 4)
+truncate-size: size: invalid integer parameter (xstrtoll returned 2)
+truncate-size: size: invalid integer parameter (xstrtoll returned 2)
+truncate-size: size: invalid integer parameter (xstrtoll returned 2)
--- /dev/null
+#!/bin/bash -
+# libguestfs
+# Copyright (C) 2009 Red Hat Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# Regression test for:
+# https://bugzilla.redhat.com/show_bug.cgi?id=557655
+# "guestfish number parsing should not use atoi, should support '0...' for octal and '0x...' for hexadecimal"
+
+set -e
+rm -f test.out
+export LANG=C
+
+../fish/guestfish >> test.out 2>&1 <<EOF
+# set-memsize is just a convenient non-daemon function that
+# takes a single integer argument.
+set-memsize 0
+get-memsize
+set-memsize 0x10
+get-memsize
+set-memsize 010
+get-memsize
+set-memsize -1073741824
+get-memsize
+set-memsize 1073741823
+get-memsize
+
+# the following should all provoke error messages:
+-set-memsize -9000000000000000
+-set-memsize 9000000000000000
+-set-memsize 0x900000000000
+-set-memsize 07777770000000000000
+-set-memsize ABC
+-set-memsize 09
+-set-memsize 123K
+-set-memsize 123L
+EOF
+
+../fish/guestfish >> test.out 2>&1 <<EOF
+alloc test1.img 10M
+run
+part-disk /dev/sda mbr
+mkfs ext2 /dev/sda1
+mount /dev/sda1 /
+
+touch /test
+
+# truncate-size takes an Int64 argument
+truncate-size /test 1234
+filesize /test
+truncate-size /test 0x4d2
+filesize /test
+truncate-size /test 02322
+filesize /test
+
+# should parse OK, but underlying filesystem will reject it:
+-truncate-size /test 0x7fffffffffffffff
+
+# larger than 64 bits, should be an error:
+-truncate-size /test 0x10000000000000000
+
+# these should all provoke parse errors:
+-truncate-size /test ABC
+-truncate-size /test 09
+-truncate-size /test 123K
+-truncate-size /test 123L
+EOF
+
+diff -u test.out rhbz557655-expected.out
+rm test.out test1.img
"change file mode",
"\
Change the mode (permissions) of C<path> to C<mode>. Only
-numeric modes are supported.");
+numeric modes are supported.
+
+I<Note>: When using this command from guestfish, C<mode>
+by default would be decimal, unless you prefix it with
+C<0> to get octal, ie. use C<0700> not C<700>.");
("chown", (RErr, [Int "owner"; Int "group"; Pathname "path"]), 35, [],
[], (* XXX Need stat command to test *)
fun (_, _, _, flags, _, _, _) -> not (List.mem NotInFish flags)
) all_functions_sorted in
+ pr "#include <config.h>\n";
+ pr "\n";
pr "#include <stdio.h>\n";
pr "#include <stdlib.h>\n";
pr "#include <string.h>\n";
pr "\n";
pr "#include <guestfs.h>\n";
pr "#include \"c-ctype.h\"\n";
+ pr "#include \"full-write.h\"\n";
+ pr "#include \"xstrtol.h\"\n";
pr "#include \"fish.h\"\n";
pr "\n";
pr " fprintf (stderr, _(\"type 'help %%s' for help on %%s\\n\"), cmd, cmd);\n";
pr " return -1;\n";
pr " }\n";
+
+ let parse_integer fn fntyp rtyp range name i =
+ pr " {\n";
+ pr " strtol_error xerr;\n";
+ pr " %s r;\n" fntyp;
+ pr "\n";
+ pr " xerr = %s (argv[%d], NULL, 0, &r, \"\");\n" fn i;
+ pr " if (xerr != LONGINT_OK) {\n";
+ pr " fprintf (stderr,\n";
+ pr " _(\"%%s: %%s: invalid integer parameter (%%s returned %%d)\\n\"),\n";
+ pr " cmd, \"%s\", \"%s\", xerr);\n" name fn;
+ pr " return -1;\n";
+ pr " }\n";
+ (match range with
+ | None -> ()
+ | Some (min, max, comment) ->
+ pr " /* %s */\n" comment;
+ pr " if (r < %s || r > %s) {\n" min max;
+ pr " fprintf (stderr, _(\"%%s: %%s: integer out of range\\n\"), cmd, \"%s\");\n"
+ name;
+ pr " return -1;\n";
+ pr " }\n";
+ pr " /* The check above should ensure this assignment does not overflow. */\n";
+ );
+ pr " %s = r;\n" name;
+ pr " }\n";
+ in
+
iteri (
fun i ->
function
| Bool name ->
pr " %s = is_true (argv[%d]) ? 1 : 0;\n" name i
| Int name ->
- pr " %s = atoi (argv[%d]);\n" name i
+ let range =
+ let min = "(-(2LL<<30))"
+ and max = "((2LL<<30)-1)"
+ and comment =
+ "The Int type in the generator is a signed 31 bit int." in
+ Some (min, max, comment) in
+ parse_integer "xstrtol" "long" "int" range name i
| Int64 name ->
- pr " %s = atoll (argv[%d]);\n" name i
+ parse_integer "xstrtoll" "long long" "int64_t" None name i
) (snd style);
(* Call C API function. *)
pr " return 0;\n"
| RBufferOut _ ->
pr " if (r == NULL) return -1;\n";
- pr " fwrite (r, size, 1, stdout);\n";
+ pr " if (full_write (1, r, size) != size) {\n";
+ pr " perror (\"write\");\n";
+ pr " free (r);\n";
+ pr " return -1;\n";
+ pr " }\n";
pr " free (r);\n";
pr " return 0;\n"
);