From: Richard Jones Date: Tue, 7 Jul 2009 15:55:51 +0000 (+0100) Subject: Merge branch 'master' of git://git.et.redhat.com/libguestfs X-Git-Tag: 1.0.56~8 X-Git-Url: http://git.annexia.org/?p=libguestfs.git;a=commitdiff_plain;h=157035503b509385084cafac8e5c5fa0afa2fef7;hp=6fb57e430c8daa06d8d938ac02a104c8aadbbda5 Merge branch 'master' of git://git.et.redhat.com/libguestfs --- diff --git a/.gitignore b/.gitignore index 8bffe89..d68982d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,24 +1,6 @@ -.deps -.libs -*.bak -*.la -*.lo -*.o *~ -*.cmi -*.cmo -*.cmx -*.cma -*.cmxa *.a -*.so -*.class -*.jar -*.hi -bindtests.tmp -ChangeLog -Makefile.in -Makefile +ABOUT-NLS aclocal.m4 appliance/debian/debirf.conf appliance/initramfs.*.img @@ -27,24 +9,34 @@ appliance/kmod.whitelist appliance/libguestfs-supermin-helper appliance/make.sh appliance/packagelist +appliance/stamp-debirf-modules +appliance/supermin.incfiles appliance/supermin-make.sh appliance/supermin-split.sh -appliance/supermin.incfiles appliance/update.sh appliance/vmlinuz.* autom4te.cache +*.bak +bindtests.tmp capitests/test-command capitests/test*.img -capitests/test*.tmp -capitests/tests.c capitests/tests +capitests/tests.c +capitests/test*.tmp +ChangeLog +*.class +*.cma +*.cmi +*.cmo +*.cmx +*.cmxa compile +config.guess config.h config.h.in -config.guess -config.sub config.log config.status +config.sub configure daemon/actions.h daemon/guestfsd @@ -53,6 +45,7 @@ daemon/missing daemon/names.c daemon/stubs.c depcomp +.deps emptydisk examples/hello examples/to-xml @@ -61,22 +54,23 @@ fish/completion.c fish/guestfish guestfish.1 guestfish-actions.pod +guestfs.3 guestfs-actions.pod guestfs-structs.pod -guestfs.3 -haskell/Bindtests.hs haskell/Bindtests -haskell/Guestfs.hs +haskell/Bindtests.hs haskell/Guestfs005Load haskell/Guestfs010Launch haskell/Guestfs050LVCreate +haskell/Guestfs.hs +*.hi html/guestfish.1.html html/guestfs.3.html html/recipes.html html/virt-inspector.1.html -images/100kallzeroes images/100kallnewlines images/100kallspaces +images/100kallzeroes images/100krandom images/10klines images/initrd @@ -85,66 +79,75 @@ initramfs initramfs.timestamp inspector/virt-inspector.1 install-sh +*.jar java/api java/Bindtests.java -java/com_redhat_et_libguestfs_GuestFS.h -java/com_redhat_et_libguestfs_GuestFS.c java/com/redhat/et/libguestfs/Dirent.java +java/com_redhat_et_libguestfs_GuestFS.c +java/com_redhat_et_libguestfs_GuestFS.h java/com/redhat/et/libguestfs/GuestFS.java +java/com/redhat/et/libguestfs/IntBool.java java/com/redhat/et/libguestfs/LV.java java/com/redhat/et/libguestfs/PV.java java/com/redhat/et/libguestfs/Stat.java java/com/redhat/et/libguestfs/StatVFS.java java/com/redhat/et/libguestfs/VG.java java/doc-stamp -missing +*.la libguestfs.pc libguestfs.spec libguestfs-*.tar.gz +.libs libtool +*.lo ltmain.sh +m4/intmax.m4 m4/libtool.m4 +m4/lt~obsolete.m4 m4/ltoptions.m4 m4/ltsugar.m4 m4/ltversion.m4 -m4/lt~obsolete.m4 -ocaml/META -ocaml/bindtests.ml +Makefile +Makefile.in +missing +*.o ocaml/bindtests +ocaml/bindtests.ml ocaml/examples/lvs -ocaml/guestfs.mli -ocaml/guestfs.ml ocaml/guestfs_c_actions.c +ocaml/guestfs.ml +ocaml/guestfs.mli +ocaml/META ocaml/t/guestfs_005_load ocaml/t/guestfs_010_launch ocaml/t/guestfs_050_lvcreate ocaml/t/guestfs_060_readdir perl/bindtests.pl perl/blib -perl/Guestfs.c perl/Guestfs.bs +perl/Guestfs.c perl/Guestfs.xs perl/lib/Sys/Guestfs.pm perl/Makefile-pl perl/Makefile.PL perl/pm_to_blib +pod2htm?.tmp po/*.gmo po/Makevars.template po/POTFILES po/remove-potcdate.sed po/stamp-it po/stamp-po -pod2htm?.tmp python/bindtests.py -python/guestfs-py.c python/guestfs.py +python/guestfs-py.c python/guestfs.pyc -ruby/Rakefile ruby/bindtests.rb -ruby/ext/guestfs/_guestfs.c ruby/ext/guestfs/extconf.h +ruby/ext/guestfs/_guestfs.c ruby/ext/guestfs/mkmf.log -src/.pod2text.data +ruby/Rakefile +*.so src/guestfs-actions.c src/guestfs-actions.h src/guestfs-bindtests.c @@ -152,5 +155,6 @@ src/guestfs_protocol.c src/guestfs_protocol.h src/guestfs_protocol.x src/guestfs-structs.h +src/.pod2text.data src/stamp-generator stamp-h1 diff --git a/ABOUT-NLS b/ABOUT-NLS deleted file mode 100644 index 2f50c66..0000000 --- a/ABOUT-NLS +++ /dev/null @@ -1,768 +0,0 @@ -Notes on the Free Translation Project -************************************* - -Free software is going international! The Free Translation Project is -a way to get maintainers of free software, translators, and users all -together, so that will gradually become able to speak many languages. -A few packages already provide translations for their messages. - - If you found this `ABOUT-NLS' file inside a distribution, you may -assume that the distributed package does use GNU `gettext' internally, -itself available at your nearest GNU archive site. But you do _not_ -need to install GNU `gettext' prior to configuring, installing or using -this package with messages translated. - - Installers will find here some useful hints. These notes also -explain how users should proceed for getting the programs to use the -available translations. They tell how people wanting to contribute and -work at translations should contact the appropriate team. - - When reporting bugs in the `intl/' directory or bugs which may be -related to internationalization, you should tell about the version of -`gettext' which is used. The information can be found in the -`intl/VERSION' file, in internationalized packages. - -Quick configuration advice -========================== - -If you want to exploit the full power of internationalization, you -should configure it using - - ./configure --with-included-gettext - -to force usage of internationalizing routines provided within this -package, despite the existence of internationalizing capabilities in the -operating system where this package is being installed. So far, only -the `gettext' implementation in the GNU C library version 2 provides as -many features (such as locale alias, message inheritance, automatic -charset conversion or plural form handling) as the implementation here. -It is also not possible to offer this additional functionality on top -of a `catgets' implementation. Future versions of GNU `gettext' will -very likely convey even more functionality. So it might be a good idea -to change to GNU `gettext' as soon as possible. - - So you need _not_ provide this option if you are using GNU libc 2 or -you have installed a recent copy of the GNU gettext package with the -included `libintl'. - -INSTALL Matters -=============== - -Some packages are "localizable" when properly installed; the programs -they contain can be made to speak your own native language. Most such -packages use GNU `gettext'. Other packages have their own ways to -internationalization, predating GNU `gettext'. - - By default, this package will be installed to allow translation of -messages. It will automatically detect whether the system already -provides the GNU `gettext' functions. If not, the GNU `gettext' own -library will be used. This library is wholly contained within this -package, usually in the `intl/' subdirectory, so prior installation of -the GNU `gettext' package is _not_ required. Installers may use -special options at configuration time for changing the default -behaviour. The commands: - - ./configure --with-included-gettext - ./configure --disable-nls - -will respectively bypass any pre-existing `gettext' to use the -internationalizing routines provided within this package, or else, -_totally_ disable translation of messages. - - When you already have GNU `gettext' installed on your system and run -configure without an option for your new package, `configure' will -probably detect the previously built and installed `libintl.a' file and -will decide to use this. This might be not what is desirable. You -should use the more recent version of the GNU `gettext' library. I.e. -if the file `intl/VERSION' shows that the library which comes with this -package is more recent, you should use - - ./configure --with-included-gettext - -to prevent auto-detection. - - The configuration process will not test for the `catgets' function -and therefore it will not be used. The reason is that even an -emulation of `gettext' on top of `catgets' could not provide all the -extensions of the GNU `gettext' library. - - Internationalized packages have usually many `po/LL.po' files, where -LL gives an ISO 639 two-letter code identifying the language. Unless -translations have been forbidden at `configure' time by using the -`--disable-nls' switch, all available translations are installed -together with the package. However, the environment variable `LINGUAS' -may be set, prior to configuration, to limit the installed set. -`LINGUAS' should then contain a space separated list of two-letter -codes, stating which languages are allowed. - -Using This Package -================== - -As a user, if your language has been installed for this package, you -only have to set the `LANG' environment variable to the appropriate -`LL_CC' combination. Here `LL' is an ISO 639 two-letter language code, -and `CC' is an ISO 3166 two-letter country code. For example, let's -suppose that you speak German and live in Germany. At the shell -prompt, merely execute `setenv LANG de_DE' (in `csh'), -`export LANG; LANG=de_DE' (in `sh') or `export LANG=de_DE' (in `bash'). -This can be done from your `.login' or `.profile' file, once and for -all. - - You might think that the country code specification is redundant. -But in fact, some languages have dialects in different countries. For -example, `de_AT' is used for Austria, and `pt_BR' for Brazil. The -country code serves to distinguish the dialects. - - The locale naming convention of `LL_CC', with `LL' denoting the -language and `CC' denoting the country, is the one use on systems based -on GNU libc. On other systems, some variations of this scheme are -used, such as `LL' or `LL_CC.ENCODING'. You can get the list of -locales supported by your system for your country by running the command -`locale -a | grep '^LL''. - - Not all programs have translations for all languages. By default, an -English message is shown in place of a nonexistent translation. If you -understand other languages, you can set up a priority list of languages. -This is done through a different environment variable, called -`LANGUAGE'. GNU `gettext' gives preference to `LANGUAGE' over `LANG' -for the purpose of message handling, but you still need to have `LANG' -set to the primary language; this is required by other parts of the -system libraries. For example, some Swedish users who would rather -read translations in German than English for when Swedish is not -available, set `LANGUAGE' to `sv:de' while leaving `LANG' to `sv_SE'. - - Special advice for Norwegian users: The language code for Norwegian -bokma*l changed from `no' to `nb' recently (in 2003). During the -transition period, while some message catalogs for this language are -installed under `nb' and some older ones under `no', it's recommended -for Norwegian users to set `LANGUAGE' to `nb:no' so that both newer and -older translations are used. - - In the `LANGUAGE' environment variable, but not in the `LANG' -environment variable, `LL_CC' combinations can be abbreviated as `LL' -to denote the language's main dialect. For example, `de' is equivalent -to `de_DE' (German as spoken in Germany), and `pt' to `pt_PT' -(Portuguese as spoken in Portugal) in this context. - -Translating Teams -================= - -For the Free Translation Project to be a success, we need interested -people who like their own language and write it well, and who are also -able to synergize with other translators speaking the same language. -Each translation team has its own mailing list. The up-to-date list of -teams can be found at the Free Translation Project's homepage, -`http://www.iro.umontreal.ca/contrib/po/HTML/', in the "National teams" -area. - - If you'd like to volunteer to _work_ at translating messages, you -should become a member of the translating team for your own language. -The subscribing address is _not_ the same as the list itself, it has -`-request' appended. For example, speakers of Swedish can send a -message to `sv-request@li.org', having this message body: - - subscribe - - Keep in mind that team members are expected to participate -_actively_ in translations, or at solving translational difficulties, -rather than merely lurking around. If your team does not exist yet and -you want to start one, or if you are unsure about what to do or how to -get started, please write to `translation@iro.umontreal.ca' to reach the -coordinator for all translator teams. - - The English team is special. It works at improving and uniformizing -the terminology in use. Proven linguistic skill are praised more than -programming skill, here. - -Available Packages -================== - -Languages are not equally supported in all packages. The following -matrix shows the current state of internationalization, as of January -2004. The matrix shows, in regard of each package, for which languages -PO files have been submitted to translation coordination, with a -translation percentage of at least 50%. - - Ready PO files af am ar az be bg bs ca cs da de el en en_GB eo es - +----------------------------------------------------+ - a2ps | [] [] [] [] | - aegis | () | - ant-phone | () | - anubis | | - ap-utils | | - aspell | [] | - bash | [] [] [] [] | - batchelor | | - bfd | [] [] | - binutils | [] [] | - bison | [] [] [] | - bluez-pin | [] [] [] | - clisp | | - clisp | [] [] [] | - console-tools | [] [] | - coreutils | [] [] [] [] | - cpio | [] [] [] | - darkstat | [] () [] | - diffutils | [] [] [] [] [] [] [] | - e2fsprogs | [] [] [] | - enscript | [] [] [] [] | - error | [] [] [] [] [] | - fetchmail | [] () [] [] [] [] | - fileutils | [] [] [] | - findutils | [] [] [] [] [] [] [] | - flex | [] [] [] [] | - fslint | | - gas | [] | - gawk | [] [] [] [] | - gbiff | [] | - gcal | [] | - gcc | [] [] | - gettext | [] [] [] [] [] | - gettext-examples | [] [] [] [] | - gettext-runtime | [] [] [] [] [] | - gettext-tools | [] [] [] | - gimp-print | [] [] [] [] [] | - gliv | | - glunarclock | [] [] | - gnubiff | [] | - gnucash | [] () [] [] | - gnucash-glossary | [] () [] | - gnupg | [] () [] [] [] [] | - gpe-aerial | [] | - gpe-beam | [] [] | - gpe-calendar | [] [] | - gpe-clock | [] [] | - gpe-conf | [] [] | - gpe-contacts | [] [] | - gpe-edit | [] | - gpe-go | [] | - gpe-login | [] [] | - gpe-ownerinfo | [] [] | - gpe-sketchbook | [] [] | - gpe-su | [] [] | - gpe-taskmanager | [] [] | - gpe-timesheet | [] | - gpe-today | [] [] | - gpe-todo | [] [] | - gphoto2 | [] [] [] [] | - gprof | [] [] [] | - gpsdrive | () () () | - gramadoir | [] | - grep | [] [] [] [] [] [] | - gretl | [] | - gtick | [] () | - hello | [] [] [] [] [] [] | - id-utils | [] [] | - indent | [] [] [] [] | - iso_3166 | [] [] [] [] [] [] [] [] [] [] | - iso_3166_1 | [] [] [] [] [] [] | - iso_3166_2 | | - iso_3166_3 | [] | - iso_4217 | [] [] [] [] | - iso_639 | | - jpilot | [] [] [] | - jtag | | - jwhois | [] | - kbd | [] [] [] [] [] | - latrine | () | - ld | [] [] | - libc | [] [] [] [] [] [] | - libgpewidget | [] [] | - libiconv | [] [] [] [] [] | - lifelines | [] () | - lilypond | [] | - lingoteach | | - lingoteach_lessons | () () | - lynx | [] [] [] [] | - m4 | [] [] [] [] | - mailutils | [] [] | - make | [] [] [] | - man-db | [] () [] [] () | - minicom | [] [] [] | - mysecretdiary | [] [] [] | - nano | [] () [] [] [] | - nano_1_0 | [] () [] [] [] | - opcodes | [] | - parted | [] [] [] [] [] | - ptx | [] [] [] [] [] | - python | | - radius | [] | - recode | [] [] [] [] [] [] [] | - rpm | [] [] | - screem | | - scrollkeeper | [] [] [] [] [] [] | - sed | [] [] [] [] [] [] | - sh-utils | [] [] [] | - shared-mime-info | | - sharutils | [] [] [] [] [] [] | - silky | () | - skencil | [] () [] | - sketch | [] () [] | - soundtracker | [] [] [] | - sp | [] | - tar | [] [] [] [] | - texinfo | [] [] [] | - textutils | [] [] [] [] | - tin | () () | - tp-robot | | - tuxpaint | [] [] [] [] [] [] [] | - unicode-han-tra... | | - unicode-transla... | | - util-linux | [] [] [] [] [] | - vorbis-tools | [] [] [] [] | - wastesedge | () | - wdiff | [] [] [] [] | - wget | [] [] [] [] [] [] | - xchat | [] [] [] [] | - xfree86_xkb_xml | [] [] | - xpad | [] | - +----------------------------------------------------+ - af am ar az be bg bs ca cs da de el en en_GB eo es - 4 0 0 1 9 4 1 40 41 60 78 17 1 5 13 68 - - et eu fa fi fr ga gl he hr hu id is it ja ko lg - +-------------------------------------------------+ - a2ps | [] [] [] () () | - aegis | | - ant-phone | [] | - anubis | [] | - ap-utils | [] | - aspell | [] [] | - bash | [] [] | - batchelor | [] [] | - bfd | [] | - binutils | [] [] | - bison | [] [] [] [] | - bluez-pin | [] [] [] [] [] | - clisp | | - clisp | [] | - console-tools | | - coreutils | [] [] [] [] [] [] | - cpio | [] [] [] [] | - darkstat | () [] [] [] | - diffutils | [] [] [] [] [] [] [] | - e2fsprogs | | - enscript | [] [] | - error | [] [] [] [] | - fetchmail | [] | - fileutils | [] [] [] [] [] [] | - findutils | [] [] [] [] [] [] [] [] [] [] [] | - flex | [] [] [] | - fslint | [] | - gas | [] | - gawk | [] [] [] | - gbiff | [] | - gcal | [] | - gcc | [] | - gettext | [] [] [] | - gettext-examples | [] [] | - gettext-runtime | [] [] [] [] [] | - gettext-tools | [] [] [] | - gimp-print | [] [] | - gliv | () | - glunarclock | [] [] [] [] | - gnubiff | [] | - gnucash | () [] | - gnucash-glossary | [] | - gnupg | [] [] [] [] [] [] [] | - gpe-aerial | [] | - gpe-beam | [] | - gpe-calendar | [] [] [] | - gpe-clock | [] | - gpe-conf | [] | - gpe-contacts | [] [] | - gpe-edit | [] [] | - gpe-go | [] | - gpe-login | [] [] | - gpe-ownerinfo | [] [] [] | - gpe-sketchbook | [] | - gpe-su | [] | - gpe-taskmanager | [] | - gpe-timesheet | [] [] [] | - gpe-today | [] [] | - gpe-todo | [] [] | - gphoto2 | [] [] [] | - gprof | [] [] | - gpsdrive | () () () | - gramadoir | [] [] | - grep | [] [] [] [] [] [] [] [] [] [] [] | - gretl | [] [] | - gtick | [] [] [] | - hello | [] [] [] [] [] [] [] [] [] [] [] [] [] | - id-utils | [] [] [] [] | - indent | [] [] [] [] [] [] [] [] [] | - iso_3166 | [] [] [] [] [] [] [] | - iso_3166_1 | [] [] [] [] [] | - iso_3166_2 | | - iso_3166_3 | | - iso_4217 | [] [] [] [] [] [] | - iso_639 | | - jpilot | [] () | - jtag | [] | - jwhois | [] [] [] [] | - kbd | [] | - latrine | [] | - ld | [] | - libc | [] [] [] [] [] [] | - libgpewidget | [] [] [] [] | - libiconv | [] [] [] [] [] [] [] [] [] | - lifelines | () | - lilypond | [] | - lingoteach | [] [] | - lingoteach_lessons | | - lynx | [] [] [] [] | - m4 | [] [] [] [] | - mailutils | | - make | [] [] [] [] [] [] | - man-db | () () | - minicom | [] [] [] [] | - mysecretdiary | [] [] | - nano | [] [] [] [] | - nano_1_0 | [] [] [] [] | - opcodes | [] | - parted | [] [] [] | - ptx | [] [] [] [] [] [] [] | - python | | - radius | [] | - recode | [] [] [] [] [] [] | - rpm | [] [] | - screem | | - scrollkeeper | [] | - sed | [] [] [] [] [] [] [] [] [] | - sh-utils | [] [] [] [] [] [] [] | - shared-mime-info | [] [] [] | - sharutils | [] [] [] [] [] | - silky | () [] () () | - skencil | [] | - sketch | [] | - soundtracker | [] [] | - sp | [] () | - tar | [] [] [] [] [] [] [] [] [] | - texinfo | [] [] [] [] | - textutils | [] [] [] [] [] [] | - tin | [] () | - tp-robot | [] | - tuxpaint | [] [] [] [] [] [] [] [] [] | - unicode-han-tra... | | - unicode-transla... | [] [] | - util-linux | [] [] [] [] () [] | - vorbis-tools | [] | - wastesedge | () | - wdiff | [] [] [] [] [] [] | - wget | [] [] [] [] [] [] [] | - xchat | [] [] [] | - xfree86_xkb_xml | [] [] | - xpad | [] [] | - +-------------------------------------------------+ - et eu fa fi fr ga gl he hr hu id is it ja ko lg - 22 2 1 26 106 28 24 8 10 41 33 1 26 33 12 0 - - lt lv mk mn ms mt nb nl nn no nso pl pt pt_BR ro ru - +-----------------------------------------------------+ - a2ps | [] [] () () [] [] [] | - aegis | () () () | - ant-phone | [] [] | - anubis | [] [] [] [] [] [] | - ap-utils | [] () [] | - aspell | [] | - bash | [] [] [] | - batchelor | [] | - bfd | [] | - binutils | [] | - bison | [] [] [] [] [] | - bluez-pin | [] [] [] | - clisp | | - clisp | [] | - console-tools | [] | - coreutils | [] [] | - cpio | [] [] [] [] [] | - darkstat | [] [] [] [] | - diffutils | [] [] [] [] [] [] | - e2fsprogs | [] | - enscript | [] [] [] [] | - error | [] [] [] | - fetchmail | [] [] () [] | - fileutils | [] [] [] | - findutils | [] [] [] [] [] | - flex | [] [] [] [] | - fslint | [] [] | - gas | | - gawk | [] [] [] | - gbiff | [] [] | - gcal | | - gcc | | - gettext | [] [] [] | - gettext-examples | [] [] [] | - gettext-runtime | [] [] [] [] | - gettext-tools | [] [] | - gimp-print | [] | - gliv | [] [] [] | - glunarclock | [] [] [] [] | - gnubiff | [] | - gnucash | [] [] () [] | - gnucash-glossary | [] [] | - gnupg | [] | - gpe-aerial | [] [] [] [] | - gpe-beam | [] [] [] [] | - gpe-calendar | [] [] [] [] | - gpe-clock | [] [] [] [] | - gpe-conf | [] [] [] [] | - gpe-contacts | [] [] [] [] | - gpe-edit | [] [] [] [] | - gpe-go | [] [] [] | - gpe-login | [] [] [] [] | - gpe-ownerinfo | [] [] [] [] | - gpe-sketchbook | [] [] [] [] | - gpe-su | [] [] [] [] | - gpe-taskmanager | [] [] [] [] | - gpe-timesheet | [] [] [] [] | - gpe-today | [] [] [] [] | - gpe-todo | [] [] [] [] | - gphoto2 | [] | - gprof | [] [] | - gpsdrive | () () [] | - gramadoir | () [] | - grep | [] [] [] [] [] | - gretl | | - gtick | [] [] [] | - hello | [] [] [] [] [] [] [] [] [] [] | - id-utils | [] [] [] [] | - indent | [] [] [] [] | - iso_3166 | [] [] [] | - iso_3166_1 | [] [] | - iso_3166_2 | | - iso_3166_3 | [] | - iso_4217 | [] [] [] [] [] [] [] [] | - iso_639 | [] | - jpilot | () () | - jtag | | - jwhois | [] [] [] [] () | - kbd | [] [] [] | - latrine | [] | - ld | | - libc | [] [] [] [] | - libgpewidget | [] [] [] | - libiconv | [] [] [] [] [] | - lifelines | | - lilypond | | - lingoteach | | - lingoteach_lessons | | - lynx | [] [] [] | - m4 | [] [] [] [] [] | - mailutils | [] [] [] | - make | [] [] [] [] | - man-db | [] | - minicom | [] [] [] [] | - mysecretdiary | [] [] [] | - nano | [] [] [] [] [] | - nano_1_0 | [] [] [] [] [] [] | - opcodes | [] [] | - parted | [] [] [] [] | - ptx | [] [] [] [] [] [] [] [] | - python | | - radius | [] [] | - recode | [] [] [] [] | - rpm | [] [] [] | - screem | | - scrollkeeper | [] [] [] [] [] | - sed | [] [] [] | - sh-utils | [] [] | - shared-mime-info | [] [] | - sharutils | [] [] | - silky | () | - skencil | [] [] | - sketch | [] [] | - soundtracker | | - sp | | - tar | [] [] [] [] [] [] | - texinfo | [] [] [] [] | - textutils | [] [] | - tin | | - tp-robot | [] | - tuxpaint | [] [] [] [] [] [] [] [] | - unicode-han-tra... | | - unicode-transla... | | - util-linux | [] [] [] | - vorbis-tools | [] [] [] | - wastesedge | | - wdiff | [] [] [] [] [] | - wget | [] [] [] | - xchat | [] [] [] | - xfree86_xkb_xml | [] [] | - xpad | [] [] | - +-----------------------------------------------------+ - lt lv mk mn ms mt nb nl nn no nso pl pt pt_BR ro ru - 1 2 0 3 12 0 10 69 6 7 1 40 26 36 76 63 - - sk sl sr sv ta th tr uk ven vi wa xh zh_CN zh_TW zu - +-----------------------------------------------------+ - a2ps | [] [] [] [] | 16 - aegis | | 0 - ant-phone | | 3 - anubis | [] [] | 9 - ap-utils | () | 3 - aspell | | 4 - bash | | 9 - batchelor | | 3 - bfd | [] [] | 6 - binutils | [] [] [] | 8 - bison | [] [] | 14 - bluez-pin | [] [] [] | 14 - clisp | | 0 - clisp | | 5 - console-tools | | 3 - coreutils | [] [] [] [] | 16 - cpio | [] [] | 14 - darkstat | [] [] [] () () | 12 - diffutils | [] [] [] | 23 - e2fsprogs | [] [] | 6 - enscript | [] [] | 12 - error | [] [] [] | 15 - fetchmail | [] [] | 11 - fileutils | [] [] [] [] [] | 17 - findutils | [] [] [] [] [] [] | 29 - flex | [] [] | 13 - fslint | | 3 - gas | [] | 3 - gawk | [] [] | 12 - gbiff | | 4 - gcal | [] [] | 4 - gcc | [] | 4 - gettext | [] [] [] [] [] | 16 - gettext-examples | [] [] [] [] [] | 14 - gettext-runtime | [] [] [] [] [] [] [] [] | 22 - gettext-tools | [] [] [] [] [] [] | 14 - gimp-print | [] [] | 10 - gliv | | 3 - glunarclock | [] [] [] | 13 - gnubiff | | 3 - gnucash | [] [] | 9 - gnucash-glossary | [] [] [] | 8 - gnupg | [] [] [] [] | 17 - gpe-aerial | [] | 7 - gpe-beam | [] | 8 - gpe-calendar | [] [] [] [] | 13 - gpe-clock | [] [] [] | 10 - gpe-conf | [] [] | 9 - gpe-contacts | [] [] [] | 11 - gpe-edit | [] [] [] [] [] | 12 - gpe-go | | 5 - gpe-login | [] [] [] [] [] | 13 - gpe-ownerinfo | [] [] [] [] | 13 - gpe-sketchbook | [] [] | 9 - gpe-su | [] [] [] | 10 - gpe-taskmanager | [] [] [] | 10 - gpe-timesheet | [] [] [] [] | 12 - gpe-today | [] [] [] [] [] | 13 - gpe-todo | [] [] [] [] | 12 - gphoto2 | [] [] [] | 11 - gprof | [] [] | 9 - gpsdrive | [] [] | 3 - gramadoir | [] | 5 - grep | [] [] [] [] | 26 - gretl | | 3 - gtick | | 7 - hello | [] [] [] [] [] | 34 - id-utils | [] [] | 12 - indent | [] [] [] [] | 21 - iso_3166 | [] [] [] [] [] [] [] | 27 - iso_3166_1 | [] [] [] | 16 - iso_3166_2 | | 0 - iso_3166_3 | | 2 - iso_4217 | [] [] [] [] [] [] | 24 - iso_639 | | 1 - jpilot | [] [] [] [] [] | 9 - jtag | [] | 2 - jwhois | () [] [] | 11 - kbd | [] [] | 11 - latrine | | 2 - ld | [] [] | 5 - libc | [] [] [] [] | 20 - libgpewidget | [] [] [] [] | 13 - libiconv | [] [] [] [] [] [] [] [] | 27 - lifelines | [] | 2 - lilypond | [] | 3 - lingoteach | | 2 - lingoteach_lessons | () | 0 - lynx | [] [] [] | 14 - m4 | [] [] | 15 - mailutils | | 5 - make | [] [] [] | 16 - man-db | [] | 5 - minicom | | 11 - mysecretdiary | [] [] | 10 - nano | [] [] [] [] | 17 - nano_1_0 | [] [] [] | 17 - opcodes | [] [] | 6 - parted | [] [] [] | 15 - ptx | [] [] | 22 - python | | 0 - radius | | 4 - recode | [] [] [] | 20 - rpm | [] [] | 9 - screem | [] [] | 2 - scrollkeeper | [] [] [] | 15 - sed | [] [] [] [] [] [] | 24 - sh-utils | [] [] | 14 - shared-mime-info | [] [] | 7 - sharutils | [] [] [] [] | 17 - silky | () | 3 - skencil | [] | 6 - sketch | [] | 6 - soundtracker | [] [] | 7 - sp | [] | 3 - tar | [] [] [] [] [] | 24 - texinfo | [] [] [] | 14 - textutils | [] [] [] [] | 16 - tin | | 1 - tp-robot | | 2 - tuxpaint | [] [] [] [] [] | 29 - unicode-han-tra... | | 0 - unicode-transla... | | 2 - util-linux | [] [] | 15 - vorbis-tools | | 8 - wastesedge | | 0 - wdiff | [] [] [] | 18 - wget | [] [] [] [] [] [] [] [] | 24 - xchat | [] [] [] [] [] | 15 - xfree86_xkb_xml | [] [] [] [] [] | 11 - xpad | | 5 - +-----------------------------------------------------+ - 63 teams sk sl sr sv ta th tr uk ven vi wa xh zh_CN zh_TW zu - 131 domains 47 19 28 83 0 0 59 13 1 1 11 0 22 22 0 1373 - - Some counters in the preceding matrix are higher than the number of -visible blocks let us expect. This is because a few extra PO files are -used for implementing regional variants of languages, or language -dialects. - - For a PO file in the matrix above to be effective, the package to -which it applies should also have been internationalized and -distributed as such by its maintainer. There might be an observable -lag between the mere existence a PO file and its wide availability in a -distribution. - - If January 2004 seems to be old, you may fetch a more recent copy of -this `ABOUT-NLS' file on most GNU archive sites. The most up-to-date -matrix with full percentage details can be found at -`http://www.iro.umontreal.ca/contrib/po/HTML/matrix.html'. - -Using `gettext' in new packages -=============================== - -If you are writing a freely available program and want to -internationalize it you are welcome to use GNU `gettext' in your -package. Of course you have to respect the GNU Library General Public -License which covers the use of the GNU `gettext' library. This means -in particular that even non-free programs can use `libintl' as a shared -library, whereas only free software can use `libintl' as a static -library or use modified versions of `libintl'. - - Once the sources are changed appropriately and the setup can handle -the use of `gettext' the only thing missing are the translations. The -Free Translation Project is also available for packages which are not -developed inside the GNU project. Therefore the information given above -applies also for every other Free Software Project. Contact -`translation@iro.umontreal.ca' to make the `.pot' files available to -the translation teams. - diff --git a/TODO b/TODO index a38a8dc..5b4c843 100644 --- a/TODO +++ b/TODO @@ -124,7 +124,6 @@ Extra commands / functionality: readlink utime / utimes / futimes / futimens / l.. more mk*temp calls - readdir / readdir-and-stat some sort of alloc/fallocate/posix_fallocate call to create empty space realpath trunc[ate??] @@ -179,3 +178,11 @@ Other initrd-* commands, such as: initrd-extract initrd-replace + +---------------------------------------------------------------------- + +Control guestfish from a pipe. + +For shell scripts - they can start up a long-running guestfish process +and intermittently send it commands. Avoids the start-up overhead, +but how do we reliably signal errors? \ No newline at end of file diff --git a/appliance/Makefile.am b/appliance/Makefile.am index 03b2a7b..7abee80 100644 --- a/appliance/Makefile.am +++ b/appliance/Makefile.am @@ -21,7 +21,11 @@ EXTRA_DIST = \ kmod.whitelist \ kmod.whitelist.in \ packagelist.in \ - init + init \ + debian/modules/install_kernel \ + debian/modules/y0_install-guestfsd \ + debian/modules/z99_final-cleanups \ + debian/debirf.conf.in # Build the root filesystem (appliance). # Currently this is arch-dependent, so it seems like putting it in @@ -92,6 +96,21 @@ $(SUPERMINIMG): supermin.incfiles supermin-make.sh endif +# Extra symlinks needed by the Debian appliance. +debirf_symlinks = \ + a0_prep-root \ + z0_remove-aptitude \ + z0_remove-locales \ + z1_clean-root +noinst_DATA = $(debirf_symlinks:%=debian/modules/%) +$(debirf_symlinks:%=debian/modules/%): stamp-debirf-modules +stamp-debirf-modules: + mkdir -p debian/modules + for f in $(debirf_symlinks); do \ + ln -sf /usr/share/debirf/modules/$$f debian/modules/$$f; \ + done + touch $@ + #---------------------------------------------------------------------- # Extra rules for testing the appliance. diff --git a/appliance/debian/debirf.conf.in b/appliance/debian/debirf.conf.in index a3dc16f..7efe25b 100644 --- a/appliance/debian/debirf.conf.in +++ b/appliance/debian/debirf.conf.in @@ -1,5 +1,5 @@ DEBIRF_LABEL="debirf-libguestfs" DEBIRF_SUITE=@REPO@ DEBIRF_MIRROR=@MIRROR@/${DEBIRF_DISTRO} -DEBIRF_KERNEL_ARCH=486 - +DEBIRF_KERNEL_ARCH=@DEBIAN_KERNEL_ARCH@ +DEBIRF_METHOD=stupid_simple diff --git a/appliance/debian/modules/a0_motd b/appliance/debian/modules/a0_motd deleted file mode 120000 index 8e3ad2f..0000000 --- a/appliance/debian/modules/a0_motd +++ /dev/null @@ -1 +0,0 @@ -/usr/share/debirf/modules/a0_motd \ No newline at end of file diff --git a/appliance/debian/modules/network b/appliance/debian/modules/network deleted file mode 120000 index 979418d..0000000 --- a/appliance/debian/modules/network +++ /dev/null @@ -1 +0,0 @@ -/usr/share/debirf/modules/network \ No newline at end of file diff --git a/appliance/debian/modules/root-bashrc b/appliance/debian/modules/root-bashrc deleted file mode 120000 index 651d030..0000000 --- a/appliance/debian/modules/root-bashrc +++ /dev/null @@ -1 +0,0 @@ -/usr/share/debirf/modules/root-bashrc \ No newline at end of file diff --git a/appliance/debian/modules/serial-terminal b/appliance/debian/modules/serial-terminal deleted file mode 120000 index a5376da..0000000 --- a/appliance/debian/modules/serial-terminal +++ /dev/null @@ -1 +0,0 @@ -/usr/share/debirf/modules/serial-terminal \ No newline at end of file diff --git a/appliance/make.sh.in b/appliance/make.sh.in index cf772e0..a132ed8 100755 --- a/appliance/make.sh.in +++ b/appliance/make.sh.in @@ -21,6 +21,7 @@ unset CDPATH set -e +set -x if [ "@DIST@" = "REDHAT" ]; then cd @top_builddir@ @@ -65,8 +66,8 @@ if [ "@DIST@" = "REDHAT" ]; then # Don't need any keyboard maps. @FEBOOTSTRAP_RUN@ initramfs -- rm -rf /lib/kbd - # Remove anything in home directory. Because this is potentially - # liable to monstrous fuck-ups, we don't put a slash before 'home'. + # Remove anything in home directory. Because of the potential for disaster + # we don't put a slash before 'home'. (cd initramfs && echo home/*) | xargs @FEBOOTSTRAP_RUN@ initramfs -- rm -rf @@ -141,5 +142,7 @@ __EOF__ elif [ "@DIST@" = "DEBIAN" ]; then cd @top_builddir@/appliance debirf make -n debian + mkdir -p @top_builddir@/initramfs + touch @top_builddir@/initramfs/fakeroot.log fi diff --git a/appliance/update.sh.in b/appliance/update.sh.in index 01e22b6..cdc441b 100755 --- a/appliance/update.sh.in +++ b/appliance/update.sh.in @@ -28,7 +28,7 @@ if [ "@DIST@" = "REDHAT" ]; then output=appliance/initramfs.@REPO@.@host_cpu@.img # Create the init script. - @FEBOOTSTRAP_INSTALL@ initramfs appliance/init /init 0755 root.root + @FEBOOTSTRAP_INSTALL@ initramfs appliance/@top_srcdir@/appliance/init /init 0755 root.root # Copy the daemon into the filesystem. @FEBOOTSTRAP_INSTALL@ initramfs daemon/guestfsd /sbin/guestfsd 0755 root.root diff --git a/autogen.sh b/autogen.sh index a1d7e27..ba4612c 100755 --- a/autogen.sh +++ b/autogen.sh @@ -20,12 +20,24 @@ set -e set -v -export AUTOMAKE='automake --foreign' + mkdir -p daemon/m4 -aclocal -libtoolize -autoreconf -i -pushd daemon autoreconf -i -popd -./configure "$@" + +CONFIGUREDIR=. + +# Run configure in BUILDDIR if it's set +if [ ! -z "$BUILDDIR" ]; then + mkdir -p $BUILDDIR + cd $BUILDDIR + + CONFIGUREDIR=.. +fi + +# If no arguments were specified and configure has run before, use the previous +# arguments +if [ $# == 0 -a -x ./config.status ]; then + ./config.status --recheck +else + $CONFIGUREDIR/configure "$@" +fi diff --git a/capitests/Makefile.am b/capitests/Makefile.am index b52d2ed..ab91755 100644 --- a/capitests/Makefile.am +++ b/capitests/Makefile.am @@ -24,8 +24,7 @@ EXTRA_DIST = \ check_PROGRAMS = tests test-command tests_SOURCES = tests.c -tests_CFLAGS = \ - -I$(top_builddir)/src -Wall +tests_CFLAGS = -I$(top_srcdir)/src -I$(top_builddir)/src -Wall tests_LDADD = $(top_builddir)/src/libguestfs.la TESTS = tests diff --git a/configure.ac b/configure.ac index 4a57fa3..c70d104 100644 --- a/configure.ac +++ b/configure.ac @@ -16,7 +16,7 @@ # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. AC_INIT([libguestfs],[1.0.55]) -AM_INIT_AUTOMAKE +AM_INIT_AUTOMAKE([foreign]) AC_CONFIG_MACRO_DIR([m4]) @@ -167,6 +167,18 @@ else test "x$DEBIRF" = "xno" && AC_MSG_ERROR([debirf must be installed]) DIST="DEBIAN" + case $host_cpu in + *86) + DEBIAN_KERNEL_ARCH=486 + ;; + x86_64) + DEBIAN_KERNEL_ARCH=amd64 + ;; + *) + DEBIAN_KERNEL_ARCH=$host_cpu + ;; + esac + AC_SUBST(DEBIAN_KERNEL_ARCH) fi AC_SUBST(DIST) diff --git a/daemon/Makefile.am b/daemon/Makefile.am index 141dfad..846a95c 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -67,7 +67,7 @@ guestfsd_SOURCES = \ wc.c \ zero.c \ zerofree.c \ - ../src/guestfs_protocol.h \ - ../src/guestfs_protocol.c + $(top_builddir)/../src/guestfs_protocol.h \ + $(top_builddir)/../src/guestfs_protocol.c guestfsd_CFLAGS = -Wall diff --git a/daemon/augeas.c b/daemon/augeas.c index 9b45f97..f75a1d6 100644 --- a/daemon/augeas.c +++ b/daemon/augeas.c @@ -1,5 +1,5 @@ /* libguestfs - the guestfsd daemon - * Copyright (C) 2009 Red Hat Inc. + * 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 @@ -122,21 +122,21 @@ do_aug_defvar (char *name, char *expr) #endif } -guestfs_aug_defnode_ret * +guestfs_int_int_bool * do_aug_defnode (char *name, char *expr, char *val) { #ifdef HAVE_AUG_DEFNODE - static guestfs_aug_defnode_ret r; + static guestfs_int_int_bool r; int created; NEED_AUG (NULL); - r.nrnodes = aug_defnode (aug, name, expr, val, &created); - if (r.nrnodes == -1) { + r.i = aug_defnode (aug, name, expr, val, &created); + if (r.i == -1) { reply_with_error ("Augeas defnode failed"); return NULL; } - r.created = created; + r.b = created; return &r; #else reply_with_error ("%s is not available", __func__); diff --git a/daemon/blockdev.c b/daemon/blockdev.c index 1b0185a..35d14bf 100644 --- a/daemon/blockdev.c +++ b/daemon/blockdev.c @@ -1,5 +1,5 @@ /* libguestfs - the guestfsd daemon - * Copyright (C) 2009 Red Hat Inc. + * 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 diff --git a/daemon/checksum.c b/daemon/checksum.c index 3654b65..bb30b05 100644 --- a/daemon/checksum.c +++ b/daemon/checksum.c @@ -1,5 +1,5 @@ /* libguestfs - the guestfsd daemon - * Copyright (C) 2009 Red Hat Inc. + * 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 diff --git a/daemon/cmp.c b/daemon/cmp.c index 04feba6..f650083 100644 --- a/daemon/cmp.c +++ b/daemon/cmp.c @@ -1,5 +1,5 @@ /* libguestfs - the guestfsd daemon - * Copyright (C) 2009 Red Hat Inc. + * 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 diff --git a/daemon/command.c b/daemon/command.c index b33f2db..3f21807 100644 --- a/daemon/command.c +++ b/daemon/command.c @@ -1,5 +1,5 @@ /* libguestfs - the guestfsd daemon - * Copyright (C) 2009 Red Hat Inc. + * 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 diff --git a/daemon/configure.ac b/daemon/configure.ac index 6ecbb8a..238532e 100644 --- a/daemon/configure.ac +++ b/daemon/configure.ac @@ -16,7 +16,7 @@ # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. AC_INIT([libguestfs-daemon],[1.0.0]) -AM_INIT_AUTOMAKE +AM_INIT_AUTOMAKE([foreign]) AC_CONFIG_MACRO_DIR([m4]) diff --git a/daemon/cpmv.c b/daemon/cpmv.c index b87d7a4..5448a97 100644 --- a/daemon/cpmv.c +++ b/daemon/cpmv.c @@ -1,5 +1,5 @@ /* libguestfs - the guestfsd daemon - * Copyright (C) 2009 Red Hat Inc. + * 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 diff --git a/daemon/daemon.h b/daemon/daemon.h index 5f22a4f..814d2b1 100644 --- a/daemon/daemon.h +++ b/daemon/daemon.h @@ -67,9 +67,9 @@ extern int root_mounted; /*-- in stubs.c (auto-generated) --*/ extern void dispatch_incoming_message (XDR *); -extern guestfs_lvm_int_pv_list *parse_command_line_pvs (void); -extern guestfs_lvm_int_vg_list *parse_command_line_vgs (void); -extern guestfs_lvm_int_lv_list *parse_command_line_lvs (void); +extern guestfs_int_lvm_pv_list *parse_command_line_pvs (void); +extern guestfs_int_lvm_vg_list *parse_command_line_vgs (void); +extern guestfs_int_lvm_lv_list *parse_command_line_lvs (void); /*-- in proto.c --*/ extern void main_loop (int sock); diff --git a/daemon/debug.c b/daemon/debug.c index d6e469b..68320a3 100644 --- a/daemon/debug.c +++ b/daemon/debug.c @@ -1,5 +1,5 @@ /* libguestfs - the guestfsd daemon - * Copyright (C) 2009 Red Hat Inc. + * 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 diff --git a/daemon/devsparts.c b/daemon/devsparts.c index 4c7a643..32d2fa8 100644 --- a/daemon/devsparts.c +++ b/daemon/devsparts.c @@ -1,5 +1,5 @@ /* libguestfs - the guestfsd daemon - * Copyright (C) 2009 Red Hat Inc. + * 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 diff --git a/daemon/df.c b/daemon/df.c index 0a7303c..73604b4 100644 --- a/daemon/df.c +++ b/daemon/df.c @@ -1,5 +1,5 @@ /* libguestfs - the guestfsd daemon - * Copyright (C) 2009 Red Hat Inc. + * 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 diff --git a/daemon/dir.c b/daemon/dir.c index 753323d..6eb86bb 100644 --- a/daemon/dir.c +++ b/daemon/dir.c @@ -1,5 +1,5 @@ /* libguestfs - the guestfsd daemon - * Copyright (C) 2009 Red Hat Inc. + * 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 diff --git a/daemon/dmesg.c b/daemon/dmesg.c index 2e58eb9..adc3426 100644 --- a/daemon/dmesg.c +++ b/daemon/dmesg.c @@ -1,5 +1,5 @@ /* libguestfs - the guestfsd daemon - * Copyright (C) 2009 Red Hat Inc. + * 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 diff --git a/daemon/dropcaches.c b/daemon/dropcaches.c index 82d95ee..a818323 100644 --- a/daemon/dropcaches.c +++ b/daemon/dropcaches.c @@ -1,5 +1,5 @@ /* libguestfs - the guestfsd daemon - * Copyright (C) 2009 Red Hat Inc. + * 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 diff --git a/daemon/du.c b/daemon/du.c index 6287a20..6f1adba 100644 --- a/daemon/du.c +++ b/daemon/du.c @@ -1,5 +1,5 @@ /* libguestfs - the guestfsd daemon - * Copyright (C) 2009 Red Hat Inc. + * 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 diff --git a/daemon/ext2.c b/daemon/ext2.c index c5e1415..5a1d0fd 100644 --- a/daemon/ext2.c +++ b/daemon/ext2.c @@ -1,5 +1,5 @@ /* libguestfs - the guestfsd daemon - * Copyright (C) 2009 Red Hat Inc. + * 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 diff --git a/daemon/file.c b/daemon/file.c index 3f07ffc..3ef7441 100644 --- a/daemon/file.c +++ b/daemon/file.c @@ -1,5 +1,5 @@ /* libguestfs - the guestfsd daemon - * Copyright (C) 2009 Red Hat Inc. + * 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 diff --git a/daemon/find.c b/daemon/find.c index 7ceeafa..85994b6 100644 --- a/daemon/find.c +++ b/daemon/find.c @@ -1,5 +1,5 @@ /* libguestfs - the guestfsd daemon - * Copyright (C) 2009 Red Hat Inc. + * 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 diff --git a/daemon/fsck.c b/daemon/fsck.c index 77e7c66..f1a9dc5 100644 --- a/daemon/fsck.c +++ b/daemon/fsck.c @@ -1,5 +1,5 @@ /* libguestfs - the guestfsd daemon - * Copyright (C) 2009 Red Hat Inc. + * 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 diff --git a/daemon/glob.c b/daemon/glob.c index f39832e..f15d5e5 100644 --- a/daemon/glob.c +++ b/daemon/glob.c @@ -1,5 +1,5 @@ /* libguestfs - the guestfsd daemon - * Copyright (C) 2009 Red Hat Inc. + * 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 diff --git a/daemon/grub.c b/daemon/grub.c index 85a5ab9..29fe294 100644 --- a/daemon/grub.c +++ b/daemon/grub.c @@ -1,5 +1,5 @@ /* libguestfs - the guestfsd daemon - * Copyright (C) 2009 Red Hat Inc. + * 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 diff --git a/daemon/guestfsd.c b/daemon/guestfsd.c index e5f2cf0..87065b9 100644 --- a/daemon/guestfsd.c +++ b/daemon/guestfsd.c @@ -1,5 +1,5 @@ /* libguestfs - the guestfsd daemon - * Copyright (C) 2009 Red Hat Inc. + * 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 @@ -572,19 +572,23 @@ commandrv (char **stdoutput, char **stderror, char * const* const argv) * trailing \n characters from the error buffer (not from stdout). */ if (stdoutput) { - *stdoutput = realloc (*stdoutput, so_size+1); - if (*stdoutput == NULL) { + void *q = realloc (*stdoutput, so_size+1); + if (q == NULL) { perror ("realloc"); - *stdoutput = NULL; - } else + free (*stdoutput); + } + *stdoutput = q; + if (*stdoutput) (*stdoutput)[so_size] = '\0'; } if (stderror) { - *stderror = realloc (*stderror, se_size+1); - if (*stderror == NULL) { + void *q = realloc (*stderror, se_size+1); + if (q == NULL) { perror ("realloc"); - *stderror = NULL; - } else { + free (*stderror); + } + *stderror = q; + if (*stderror) { (*stderror)[se_size] = '\0'; se_size--; while (se_size >= 0 && (*stderror)[se_size] == '\n') diff --git a/daemon/headtail.c b/daemon/headtail.c index b522c55..6d24851 100644 --- a/daemon/headtail.c +++ b/daemon/headtail.c @@ -1,5 +1,5 @@ /* libguestfs - the guestfsd daemon - * Copyright (C) 2009 Red Hat Inc. + * 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 diff --git a/daemon/hexdump.c b/daemon/hexdump.c index ae7df92..a582c57 100644 --- a/daemon/hexdump.c +++ b/daemon/hexdump.c @@ -1,5 +1,5 @@ /* libguestfs - the guestfsd daemon - * Copyright (C) 2009 Red Hat Inc. + * 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 diff --git a/daemon/initrd.c b/daemon/initrd.c index 2d6cbdd..7b32a08 100644 --- a/daemon/initrd.c +++ b/daemon/initrd.c @@ -1,5 +1,5 @@ /* libguestfs - the guestfsd daemon - * Copyright (C) 2009 Red Hat Inc. + * 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 diff --git a/daemon/ls.c b/daemon/ls.c index 61055b6..a440080 100644 --- a/daemon/ls.c +++ b/daemon/ls.c @@ -1,5 +1,5 @@ /* libguestfs - the guestfsd daemon - * Copyright (C) 2009 Red Hat Inc. + * 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 diff --git a/daemon/lvm.c b/daemon/lvm.c index 0fba447..01b6435 100644 --- a/daemon/lvm.c +++ b/daemon/lvm.c @@ -1,5 +1,5 @@ /* libguestfs - the guestfsd daemon - * Copyright (C) 2009 Red Hat Inc. + * 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 @@ -152,19 +152,19 @@ do_lvs (void) * the code. That code is in stubs.c, and it is generated as usual * by generator.ml. */ -guestfs_lvm_int_pv_list * +guestfs_int_lvm_pv_list * do_pvs_full (void) { return parse_command_line_pvs (); } -guestfs_lvm_int_vg_list * +guestfs_int_lvm_vg_list * do_vgs_full (void) { return parse_command_line_vgs (); } -guestfs_lvm_int_lv_list * +guestfs_int_lvm_lv_list * do_lvs_full (void) { return parse_command_line_lvs (); diff --git a/daemon/mknod.c b/daemon/mknod.c index 5af791f..315ea7d 100644 --- a/daemon/mknod.c +++ b/daemon/mknod.c @@ -1,5 +1,5 @@ /* libguestfs - the guestfsd daemon - * Copyright (C) 2009 Red Hat Inc. + * 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 diff --git a/daemon/mount.c b/daemon/mount.c index b0cb496..1820f8a 100644 --- a/daemon/mount.c +++ b/daemon/mount.c @@ -1,5 +1,5 @@ /* libguestfs - the guestfsd daemon - * Copyright (C) 2009 Red Hat Inc. + * 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 diff --git a/daemon/ntfs.c b/daemon/ntfs.c index 87881b1..26c8d50 100644 --- a/daemon/ntfs.c +++ b/daemon/ntfs.c @@ -1,5 +1,5 @@ /* libguestfs - the guestfsd daemon - * Copyright (C) 2009 Red Hat Inc. + * 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 diff --git a/daemon/pingdaemon.c b/daemon/pingdaemon.c index 5417a1d..0a69afa 100644 --- a/daemon/pingdaemon.c +++ b/daemon/pingdaemon.c @@ -1,5 +1,5 @@ /* libguestfs - the guestfsd daemon - * Copyright (C) 2009 Red Hat Inc. + * 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 diff --git a/daemon/proto.c b/daemon/proto.c index 3ca4316..acd6601 100644 --- a/daemon/proto.c +++ b/daemon/proto.c @@ -1,5 +1,5 @@ /* libguestfs - the guestfsd daemon - * Copyright (C) 2009 Red Hat Inc. + * 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 @@ -266,9 +266,14 @@ reply (xdrproc_t xdrp, char *ret) } if (xdrp) { + /* This can fail if the reply body is too large, for example + * if it exceeds the maximum message size. In that case + * we want to return an error message instead. (RHBZ#509597). + */ if (!(*xdrp) (&xdr, ret)) { - fprintf (stderr, "guestfsd: failed to encode reply body\n"); - exit (1); + reply_with_perror ("guestfsd: failed to encode reply body\n"); + xdr_destroy (&xdr); + return; } } diff --git a/daemon/readdir.c b/daemon/readdir.c index cea6fdd..e3851db 100644 --- a/daemon/readdir.c +++ b/daemon/readdir.c @@ -1,5 +1,5 @@ /* libguestfs - the guestfsd daemon - * Copyright (C) 2009 Red Hat Inc. + * 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 @@ -68,6 +68,8 @@ do_readdir (char *path) if (!p || !v.name) { reply_with_perror ("allocate"); free (ret->guestfs_int_dirent_list_val); + free (p); + free (v.name); free (ret); closedir (dir); return NULL; diff --git a/daemon/scrub.c b/daemon/scrub.c index 9b6d49d..2f14bcb 100644 --- a/daemon/scrub.c +++ b/daemon/scrub.c @@ -1,5 +1,5 @@ /* libguestfs - the guestfsd daemon - * Copyright (C) 2009 Red Hat Inc. + * 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 diff --git a/daemon/sfdisk.c b/daemon/sfdisk.c index f1726fc..f512e26 100644 --- a/daemon/sfdisk.c +++ b/daemon/sfdisk.c @@ -1,5 +1,5 @@ /* libguestfs - the guestfsd daemon - * Copyright (C) 2009 Red Hat Inc. + * 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 diff --git a/daemon/sleep.c b/daemon/sleep.c index 2cf3ff7..3b5d395 100644 --- a/daemon/sleep.c +++ b/daemon/sleep.c @@ -1,5 +1,5 @@ /* libguestfs - the guestfsd daemon - * Copyright (C) 2009 Red Hat Inc. + * 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 diff --git a/daemon/stat.c b/daemon/stat.c index 6b12f4c..da360ce 100644 --- a/daemon/stat.c +++ b/daemon/stat.c @@ -1,5 +1,5 @@ /* libguestfs - the guestfsd daemon - * Copyright (C) 2009 Red Hat Inc. + * 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 diff --git a/daemon/strings.c b/daemon/strings.c index d78f9fd..2c52532 100644 --- a/daemon/strings.c +++ b/daemon/strings.c @@ -1,5 +1,5 @@ /* libguestfs - the guestfsd daemon - * Copyright (C) 2009 Red Hat Inc. + * 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 diff --git a/daemon/swap.c b/daemon/swap.c index 7dac96e..faed7f6 100644 --- a/daemon/swap.c +++ b/daemon/swap.c @@ -1,5 +1,5 @@ /* libguestfs - the guestfsd daemon - * Copyright (C) 2009 Red Hat Inc. + * 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 diff --git a/daemon/sync.c b/daemon/sync.c index 70962df..b353b6c 100644 --- a/daemon/sync.c +++ b/daemon/sync.c @@ -1,5 +1,5 @@ /* libguestfs - the guestfsd daemon - * Copyright (C) 2009 Red Hat Inc. + * 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 diff --git a/daemon/tar.c b/daemon/tar.c index 0320604..9540827 100644 --- a/daemon/tar.c +++ b/daemon/tar.c @@ -1,5 +1,5 @@ /* libguestfs - the guestfsd daemon - * Copyright (C) 2009 Red Hat Inc. + * 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 diff --git a/daemon/umask.c b/daemon/umask.c index ad8573d..22d2cc9 100644 --- a/daemon/umask.c +++ b/daemon/umask.c @@ -1,5 +1,5 @@ /* libguestfs - the guestfsd daemon - * Copyright (C) 2009 Red Hat Inc. + * 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 diff --git a/daemon/upload.c b/daemon/upload.c index 0f737af..6c5f6dc 100644 --- a/daemon/upload.c +++ b/daemon/upload.c @@ -1,5 +1,5 @@ /* libguestfs - the guestfsd daemon - * Copyright (C) 2009 Red Hat Inc. + * 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 diff --git a/daemon/wc.c b/daemon/wc.c index 91e1942..370ffdd 100644 --- a/daemon/wc.c +++ b/daemon/wc.c @@ -1,5 +1,5 @@ /* libguestfs - the guestfsd daemon - * Copyright (C) 2009 Red Hat Inc. + * 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 diff --git a/daemon/zero.c b/daemon/zero.c index 9d793e1..9c803d8 100644 --- a/daemon/zero.c +++ b/daemon/zero.c @@ -1,5 +1,5 @@ /* libguestfs - the guestfsd daemon - * Copyright (C) 2009 Red Hat Inc. + * 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 diff --git a/daemon/zerofree.c b/daemon/zerofree.c index ed7a3fc..8000bb3 100644 --- a/daemon/zerofree.c +++ b/daemon/zerofree.c @@ -1,5 +1,5 @@ /* libguestfs - the guestfsd daemon - * Copyright (C) 2009 Red Hat Inc. + * 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 diff --git a/examples/Makefile.am b/examples/Makefile.am index 13302d9..fb3d656 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -3,11 +3,11 @@ noinst_PROGRAMS = hello to-xml hello_SOURCES = hello.c -hello_CFLAGS = -I$(top_builddir)/src -Wall +hello_CFLAGS = -I$(top_srcdir)/src -I$(top_builddir)/src -Wall hello_LDADD = $(top_builddir)/src/libguestfs.la to_xml_SOURCES = to-xml.c -to_xml_CFLAGS = -I$(top_builddir)/src -Wall +to_xml_CFLAGS = -I$(top_srcdir)/src -I$(top_builddir)/src -Wall to_xml_LDADD = $(top_builddir)/src/libguestfs.la CLEANFILES = $(noinst_PROGRAMS) diff --git a/fish/Makefile.am b/fish/Makefile.am index 03e872c..1439a5d 100644 --- a/fish/Makefile.am +++ b/fish/Makefile.am @@ -32,6 +32,6 @@ guestfish_SOURCES = \ time.c guestfish_CFLAGS = \ - -I$(top_builddir)/src -Wall \ + -I$(top_srcdir)/src -I$(top_builddir)/src -Wall \ -DGUESTFS_DEFAULT_PATH='"$(libdir)/guestfs"' guestfish_LDADD = $(top_builddir)/src/libguestfs.la $(LIBREADLINE) diff --git a/fish/alloc.c b/fish/alloc.c index cdce73c..a7d115a 100644 --- a/fish/alloc.c +++ b/fish/alloc.c @@ -1,5 +1,5 @@ /* guestfish - the filesystem interactive shell - * Copyright (C) 2009 Red Hat Inc. + * 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 diff --git a/fish/destpaths.c b/fish/destpaths.c index 90970de..a9d65a5 100644 --- a/fish/destpaths.c +++ b/fish/destpaths.c @@ -53,17 +53,23 @@ * devices and LVM names. */ -int complete_dest_paths = 0; /* SEE NOTE */ +int complete_dest_paths = 1; -/* NOTE: This is currently disabled by default (with no way to - * enable it). That's because it's not particularly natural. - * - * Also there is a quite serious performance problem. When listing - * even moderately long directories, this takes many seconds. The - * reason is because it calls guestfs_is_dir on each directory - * entry, thus lots of round trips to the server. We could have - * a "readdir and stat each entry" call to ease this. - */ +struct word { + char *name; + int is_dir; +}; + +static void +free_words (struct word *words, int nr_words) +{ + size_t i; + + /* NB. 'words' array is NOT NULL-terminated. */ + for (i = 0; i < nr_words; ++i) + free (words[i].name); + free (words); +} char * complete_dest_paths_generator (const char *text, int state) @@ -71,9 +77,8 @@ complete_dest_paths_generator (const char *text, int state) #ifdef HAVE_LIBREADLINE static size_t len, index; - static char **words = NULL; + static struct word *words = NULL; static size_t nr_words = 0; - char *word; guestfs_error_handler_cb old_error_cb; void *old_error_cb_data; @@ -94,13 +99,7 @@ complete_dest_paths_generator (const char *text, int state) len = strlen (text); index = 0; - if (words) { - size_t i; - /* NB. 'words' array is NOT NULL-terminated. */ - for (i = 0; i < nr_words; ++i) - free (words[i]); - free (words); - } + if (words) free_words (words, nr_words); words = NULL; nr_words = 0; @@ -111,17 +110,24 @@ complete_dest_paths_generator (const char *text, int state) #define APPEND_STRS_AND_FREE \ do { \ if (strs) { \ + size_t i; \ size_t n = count_strings (strs); \ - if ( ! xalloc_oversized (nr_words + n, sizeof (char *))) { \ - char *w = realloc (words, sizeof (char *) * (nr_words + n)); \ + \ + if ( ! xalloc_oversized (nr_words + n, sizeof (struct word))) { \ + struct word *w; \ + w = realloc (words, sizeof (struct word) * (nr_words + n)); \ + \ if (w == NULL) { \ - free (words); \ + free_words (words, nr_words); \ words = NULL; \ nr_words = 0; \ } else { \ - size_t i; \ - for (i = 0; i < n; ++i) \ - words[nr_words++] = strs[i]; \ + words = w; \ + for (i = 0; i < n; ++i) { \ + words[nr_words].name = strs[i]; \ + words[nr_words].is_dir = 0; \ + nr_words++; \ + } \ } \ free (strs); \ } \ @@ -146,30 +152,51 @@ complete_dest_paths_generator (const char *text, int state) * in that directory, otherwise list everything in / */ char *p, *dir; + struct guestfs_dirent_list *dirents; p = strrchr (text, '/'); dir = p && p > text ? strndup (text, p - text) : strdup ("/"); if (dir) { - strs = guestfs_ls (g, dir); + dirents = guestfs_readdir (g, dir); - /* Prepend directory to names. */ - if (strs) { + /* Prepend directory to names before adding them to the list + * of words. + */ + if (dirents) { size_t i; - for (i = 0; strs[i]; ++i) { + + for (i = 0; i < dirents->len; ++i) { int err; - if (strcmp (dir, "/") == 0) - err = asprintf (&p, "/%s", strs[i]); - else - err = asprintf (&p, "%s/%s", dir, strs[i]); - if (0 <= err) { - free (strs[i]); - strs[i] = p; + + if (strcmp (dirents->val[i].name, ".") != 0 && + strcmp (dirents->val[i].name, "..") != 0) { + if (strcmp (dir, "/") == 0) + err = asprintf (&p, "/%s", dirents->val[i].name); + else + err = asprintf (&p, "%s/%s", dir, dirents->val[i].name); + if (err >= 0) { + if (!xalloc_oversized (nr_words+1, sizeof (struct word))) { + struct word *w; + + w = realloc (words, sizeof (struct word) * (nr_words+1)); + if (w == NULL) { + free_words (words, nr_words); + words = NULL; + nr_words = 0; + } + else { + words = w; + words[nr_words].name = p; + words[nr_words].is_dir = dirents->val[i].ftyp == 'd'; + nr_words++; + } + } + } } } - } - free (dir); - APPEND_STRS_AND_FREE; + guestfs_free_dirent_list (dirents); + } } } @@ -185,18 +212,16 @@ complete_dest_paths_generator (const char *text, int state) /* Complete the string. */ while (index < nr_words) { - word = words[index]; + struct word *word; + + word = &words[index]; index++; - if (strncasecmp (word, text, len) == 0) { - /* Is it a directory? */ - if (strncmp (word, "/dev/", 5) != 0) { - SAVE_ERROR_CB - if (guestfs_is_dir (g, word) > 0) - rl_completion_append_character = '/'; - RESTORE_ERROR_CB - } - return strdup (word); + if (strncasecmp (word->name, text, len) == 0) { + if (word->is_dir) + rl_completion_append_character = '/'; + + return strdup (word->name); } } diff --git a/fish/echo.c b/fish/echo.c index b4b5cf1..33992d4 100644 --- a/fish/echo.c +++ b/fish/echo.c @@ -1,5 +1,5 @@ /* guestfish - the filesystem interactive shell - * Copyright (C) 2009 Red Hat Inc. + * 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 diff --git a/fish/edit.c b/fish/edit.c index c72ad1d..3e6973e 100644 --- a/fish/edit.c +++ b/fish/edit.c @@ -1,5 +1,5 @@ /* guestfish - the filesystem interactive shell - * Copyright (C) 2009 Red Hat Inc. + * 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 diff --git a/fish/fish.c b/fish/fish.c index 59348c3..25483a1 100644 --- a/fish/fish.c +++ b/fish/fish.c @@ -1,5 +1,5 @@ /* guestfish - the filesystem interactive shell - * Copyright (C) 2009 Red Hat Inc. + * 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 @@ -732,8 +732,12 @@ issue_command (const char *cmd, char *argv[], const char *pipecmd) else r = run_action (cmd, argc, argv); + /* Always flush stdout after every command, so that messages, results + * etc appear immediately. + */ + fflush (stdout); + if (pipecmd) { - fflush (stdout); close (1); dup2 (stdout_saved_fd, 1); close (stdout_saved_fd); diff --git a/fish/glob.c b/fish/glob.c index a8ac58a..581bc28 100644 --- a/fish/glob.c +++ b/fish/glob.c @@ -1,5 +1,5 @@ /* guestfish - the filesystem interactive shell - * Copyright (C) 2009 Red Hat Inc. + * 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 diff --git a/fish/lcd.c b/fish/lcd.c index 359d178..e631f21 100644 --- a/fish/lcd.c +++ b/fish/lcd.c @@ -1,5 +1,5 @@ /* guestfish - the filesystem interactive shell - * Copyright (C) 2009 Red Hat Inc. + * 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 diff --git a/fish/more.c b/fish/more.c index 8bc9d95..9abb51b 100644 --- a/fish/more.c +++ b/fish/more.c @@ -1,5 +1,5 @@ /* guestfish - the filesystem interactive shell - * Copyright (C) 2009 Red Hat Inc. + * 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 diff --git a/fish/time.c b/fish/time.c index d2a2066..aae9afe 100644 --- a/fish/time.c +++ b/fish/time.c @@ -1,5 +1,5 @@ /* guestfish - the filesystem interactive shell - * Copyright (C) 2009 Red Hat Inc. + * 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 diff --git a/guestfish.pod b/guestfish.pod index 0c3fda6..4341e2a 100644 --- a/guestfish.pod +++ b/guestfish.pod @@ -49,13 +49,13 @@ Remove C (in reality not such a great idea): =head2 As an interactive shell $ guestfish - + Welcome to guestfish, the libguestfs filesystem interactive shell for editing virtual machine filesystems. - + Type: 'help' for help with commands 'quit' to quit the shell - + > help =head2 As a script interpreter diff --git a/guestfs.pod b/guestfs.pod index a41fd27..c7310a6 100644 --- a/guestfs.pod +++ b/guestfs.pod @@ -7,7 +7,7 @@ guestfs - Library for accessing and modifying virtual machine images =head1 SYNOPSIS #include - + guestfs_h *handle = guestfs_create (); guestfs_add_drive (handle, "guest.img"); guestfs_launch (handle); @@ -49,28 +49,28 @@ If you are using the high-level API, then you should call the functions in the following order: guestfs_h *handle = guestfs_create (); - + guestfs_add_drive (handle, "guest.img"); /* call guestfs_add_drive additional times if the guest has * multiple disks */ - + guestfs_launch (handle); guestfs_wait_ready (handle); /* now you can examine what partitions, LVs etc are available * you have to mount / at least - */ + */ guestfs_mount (handle, "/dev/sda1", "/"); /* now you can perform actions on the guest disk image */ guestfs_touch (handle, "/hello"); - + /* you only need to call guestfs_sync if you have made * changes to the guest image */ guestfs_sync (handle); - + guestfs_close (handle); C and all of the actions including C @@ -168,7 +168,7 @@ If you set C to C then I handler is called. Returns the current error handler callback. -=head2 guestfs_set_out_of_memory_handler +=head2 guestfs_set_out_of_memory_handler typedef void (*guestfs_abort_cb) (void); int guestfs_set_out_of_memory_handler (guestfs_h *handle, diff --git a/haskell/Makefile.am b/haskell/Makefile.am index 3cb721f..dcaf18a 100644 --- a/haskell/Makefile.am +++ b/haskell/Makefile.am @@ -30,7 +30,7 @@ TESTS = run-bindtests Guestfs005Load Guestfs010Launch Guestfs050LVCreate check_DATA = Bindtests -GHCFLAGS = -I$(abs_top_builddir)/src -L$(abs_top_builddir)/src/.libs +GHCFLAGS = -I$(top_builddir)/src -L$(top_builddir)/src/.libs Bindtests: Bindtests.hs Guestfs.hs $(GHC) $(GHCFLAGS) -main-is $(shell basename $@) --make -o $@ $< -lguestfs @@ -44,4 +44,4 @@ Guestfs010Launch: Guestfs010Launch.hs Guestfs.hs Guestfs050LVCreate: Guestfs050LVCreate.hs Guestfs.hs $(GHC) $(GHCFLAGS) -main-is $(shell basename $@) --make -o $@ $< -lguestfs -endif \ No newline at end of file +endif diff --git a/images/Makefile.am b/images/Makefile.am index 8855382..9353e17 100644 --- a/images/Makefile.am +++ b/images/Makefile.am @@ -28,9 +28,23 @@ CLEANFILES = \ 100kallzeroes 100kallnewlines 100kallspaces 100krandom 10klines \ initrd -squash_files = helloworld.tar helloworld.tar.gz empty known-1 known-2 known-3 \ - 100kallzeroes 100kallnewlines 100kallspaces 100krandom 10klines \ - initrd +squash_files_src = \ + $(srcdir)/helloworld.tar \ + $(srcdir)/helloworld.tar.gz \ + $(srcdir)/empty \ + $(srcdir)/known-1 \ + $(srcdir)/known-2 \ + $(srcdir)/known-3 + +squash_files_build = \ + $(builddir)/100kallzeroes \ + $(builddir)/100kallnewlines \ + $(builddir)/100kallspaces \ + $(builddir)/100krandom \ + $(builddir)/10klines \ + $(builddir)/initrd + +squash_files = $(squash_files_src) $(squash_files_build) test.sqsh: $(squash_files) rm -f $@ diff --git a/inspector/Makefile.am b/inspector/Makefile.am index b43870d..a1df2ab 100644 --- a/inspector/Makefile.am +++ b/inspector/Makefile.am @@ -23,7 +23,7 @@ if HAVE_INSPECTOR man_MANS = virt-inspector.1 -noinst_DATA = ../html/virt-inspector.1.html +noinst_DATA = @top_builddir@/html/virt-inspector.1.html virt-inspector.1: virt-inspector.pl $(POD2MAN) \ @@ -32,8 +32,9 @@ virt-inspector.1: virt-inspector.pl --release "$(PACKAGE_NAME)-$(PACKAGE_VERSION)" \ $< > $@ -../html/virt-inspector.1.html: virt-inspector.pl - cd .. && pod2html \ +@top_builddir@/html/virt-inspector.1.html: virt-inspector.pl + mkdir -p @top_builddir@/html + cd @top_builddir@ && pod2html \ --css 'pod.css' \ --title 'virt-inspector, display OS version, kernel, drivers, mount points, applications, etc. in a virtual machine' \ --htmldir html \ diff --git a/inspector/virt-inspector.pl b/inspector/virt-inspector.pl index 66b1553..3557a38 100755 --- a/inspector/virt-inspector.pl +++ b/inspector/virt-inspector.pl @@ -968,7 +968,7 @@ elsif ($output eq "perl") { elsif ($output eq "yaml") { die "virt-inspector: no YAML support\n" unless exists $INC{"YAML/Any.pm"}; - + print Dump(\%oses); } diff --git a/java/Makefile.am b/java/Makefile.am index ea90a48..b682747 100644 --- a/java/Makefile.am +++ b/java/Makefile.am @@ -15,18 +15,18 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -CPTH = com/redhat/et/libguestfs +java_prefix = com/redhat/et/libguestfs java_sources = \ - $(CPTH)/LibGuestFSException.java \ - $(CPTH)/IntBool.java \ - $(CPTH)/PV.java \ - $(CPTH)/VG.java \ - $(CPTH)/LV.java \ - $(CPTH)/Stat.java \ - $(CPTH)/StatVFS.java \ - $(CPTH)/Dirent.java \ - $(CPTH)/GuestFS.java + $(java_prefix)/LibGuestFSException.java \ + $(java_prefix)/IntBool.java \ + $(java_prefix)/PV.java \ + $(java_prefix)/VG.java \ + $(java_prefix)/LV.java \ + $(java_prefix)/Stat.java \ + $(java_prefix)/StatVFS.java \ + $(java_prefix)/Dirent.java \ + $(java_prefix)/GuestFS.java java_tests = \ Bindtests.java \ @@ -50,7 +50,7 @@ libguestfs_jardir = $(JAR_INSTALL_DIR) libguestfs_jar_DATA = libguestfs-${VERSION}.jar libguestfs_jar_class_files = $(java_sources:.java=.class) $(libguestfs_jar_class_files): %.class: %.java - $(JAVAC) $(JAVAC_FLAGS) -classpath $(CPTH) $(java_sources) + $(JAVAC) $(JAVAC_FLAGS) -d @builddir@ -classpath @srcdir@:@builddir@ -sourcepath @srcdir@:@builddir@ $< libguestfs-${VERSION}.jar: $(libguestfs_jar_class_files) $(JAR) cf $@ $^ @@ -64,12 +64,12 @@ libguestfs_jni_la_SOURCES = \ libguestfs_jni_la_LIBADD = $(top_builddir)/src/libguestfs.la libguestfs_jni_la_LDFLAGS = -version-info $(JNI_VERSION_INFO) -libguestfs_jni_la_CFLAGS = -Wall -I$(top_builddir)/src $(JNI_CFLAGS) +libguestfs_jni_la_CFLAGS = -Wall -I$(top_srcdir)/src -I$(top_builddir)/src $(JNI_CFLAGS) BUILT_SOURCES = com_redhat_et_libguestfs_GuestFS.h -com_redhat_et_libguestfs_GuestFS.h: $(CPTH)/GuestFS.class - $(JAVAH) -classpath .:$(CPTH) com.redhat.et.libguestfs.GuestFS +com_redhat_et_libguestfs_GuestFS.h: $(java_prefix)/GuestFS.class + $(JAVAH) -classpath @srcdir@:@builddir@ com.redhat.et.libguestfs.GuestFS # Documentation. diff --git a/java/com/redhat/et/libguestfs/IntBool.java b/java/com/redhat/et/libguestfs/IntBool.java deleted file mode 100644 index 23ea68f..0000000 --- a/java/com/redhat/et/libguestfs/IntBool.java +++ /dev/null @@ -1,30 +0,0 @@ -/* libguestfs Java bindings - * Copyright (C) 2009 Red Hat Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package com.redhat.et.libguestfs; - -/** - * A pair (int, boolean) - * - * @author rjones - * @see Exception - */ -public class IntBool { - public int i; - public boolean b; -} diff --git a/libguestfs.pc.in b/libguestfs.pc.in index bcbc241..679ed7e 100644 --- a/libguestfs.pc.in +++ b/libguestfs.pc.in @@ -7,5 +7,5 @@ Name: libguestfs Version: @VERSION@ Description: libguestfs library for accessing and modifying VM images Requires: -Cflags: +Cflags: Libs: -lguestfs @LIBS@ diff --git a/m4/intltool.m4 b/m4/intltool.m4 index 122d773..ba4c0b1 100644 --- a/m4/intltool.m4 +++ b/m4/intltool.m4 @@ -55,23 +55,23 @@ if test -z "$INTLTOOL_UPDATE" -o -z "$INTLTOOL_MERGE" -o -z "$INTLTOOL_EXTRACT"; AC_MSG_ERROR([The intltool scripts were not found. Please install intltool.]) fi - INTLTOOL_DESKTOP_RULE='%.desktop: %.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' -INTLTOOL_DIRECTORY_RULE='%.directory: %.directory.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' - INTLTOOL_KEYS_RULE='%.keys: %.keys.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -k -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' - INTLTOOL_PROP_RULE='%.prop: %.prop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_DESKTOP_RULE='%.desktop: %.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' +INTLTOOL_DIRECTORY_RULE='%.directory: %.directory.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_KEYS_RULE='%.keys: %.keys.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -k -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_PROP_RULE='%.prop: %.prop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' INTLTOOL_OAF_RULE='%.oaf: %.oaf.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -o -p $(top_srcdir)/po $< [$]@' - INTLTOOL_PONG_RULE='%.pong: %.pong.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' - INTLTOOL_SERVER_RULE='%.server: %.server.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -o -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' - INTLTOOL_SHEET_RULE='%.sheet: %.sheet.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' -INTLTOOL_SOUNDLIST_RULE='%.soundlist: %.soundlist.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' - INTLTOOL_UI_RULE='%.ui: %.ui.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' - INTLTOOL_XML_RULE='%.xml: %.xml.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' - INTLTOOL_XML_NOMERGE_RULE='%.xml: %.xml.in $(INTLTOOL_MERGE) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u /tmp $< [$]@' - INTLTOOL_XAM_RULE='%.xam: %.xml.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' - INTLTOOL_KBD_RULE='%.kbd: %.kbd.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -m -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' - INTLTOOL_CAVES_RULE='%.caves: %.caves.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' - INTLTOOL_SCHEMAS_RULE='%.schemas: %.schemas.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -s -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' - INTLTOOL_THEME_RULE='%.theme: %.theme.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_PONG_RULE='%.pong: %.pong.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_SERVER_RULE='%.server: %.server.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -o -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_SHEET_RULE='%.sheet: %.sheet.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' +INTLTOOL_SOUNDLIST_RULE='%.soundlist: %.soundlist.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_UI_RULE='%.ui: %.ui.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_XML_RULE='%.xml: %.xml.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_XML_NOMERGE_RULE='%.xml: %.xml.in $(INTLTOOL_MERGE) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u /tmp $< [$]@' + INTLTOOL_XAM_RULE='%.xam: %.xml.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_KBD_RULE='%.kbd: %.kbd.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -m -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_CAVES_RULE='%.caves: %.caves.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_SCHEMAS_RULE='%.schemas: %.schemas.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -s -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_THEME_RULE='%.theme: %.theme.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' INTLTOOL_SERVICE_RULE='%.service: %.service.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' INTLTOOL_POLICY_RULE='%.policy: %.policy.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' diff --git a/m4/intmax.m4 b/m4/intmax.m4 deleted file mode 100644 index dfb08cc..0000000 --- a/m4/intmax.m4 +++ /dev/null @@ -1,32 +0,0 @@ -# intmax.m4 serial 1 (gettext-0.12) -dnl Copyright (C) 2002-2003 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. - -dnl From Bruno Haible. -dnl Test whether the system has the 'intmax_t' type, but don't attempt to -dnl find a replacement if it is lacking. - -AC_DEFUN([gt_TYPE_INTMAX_T], -[ - AC_REQUIRE([jm_AC_HEADER_INTTYPES_H]) - AC_REQUIRE([jm_AC_HEADER_STDINT_H]) - AC_CACHE_CHECK(for intmax_t, gt_cv_c_intmax_t, - [AC_TRY_COMPILE([ -#include -#include -#if HAVE_STDINT_H_WITH_UINTMAX -#include -#endif -#if HAVE_INTTYPES_H_WITH_UINTMAX -#include -#endif -], [intmax_t x = -1;], gt_cv_c_intmax_t=yes, gt_cv_c_intmax_t=no)]) - if test $gt_cv_c_intmax_t = yes; then - AC_DEFINE(HAVE_INTMAX_T, 1, - [Define if you have the 'intmax_t' type in or .]) - fi -]) diff --git a/ocaml/Makefile.am b/ocaml/Makefile.am index bed1f92..bf9760c 100644 --- a/ocaml/Makefile.am +++ b/ocaml/Makefile.am @@ -39,10 +39,10 @@ mlguestfs.cmxa: guestfs_c.o guestfs_c_actions.o guestfs.cmx $(OCAMLMKLIB) -o mlguestfs $^ -L$(top_builddir)/src/.libs -lguestfs guestfs_c.o: guestfs_c.c - $(CC) $(CFLAGS) -I$(OCAMLLIB) -I$(top_builddir)/src -fPIC -Wall -c $< + $(CC) $(CFLAGS) -I$(OCAMLLIB) -I$(top_srcdir)/ocaml -I$(top_srcdir)/src -I$(top_builddir)/src -fPIC -Wall -c $< guestfs_c_actions.o: guestfs_c_actions.c - $(CC) $(CFLAGS) -I$(OCAMLLIB) -I$(top_builddir)/src -fPIC -Wall -c $< + $(CC) $(CFLAGS) -I$(OCAMLLIB) -I$(top_srcdir)/ocaml -I$(top_srcdir)/src -I$(top_builddir)/src -fPIC -Wall -c $< TESTS_ENVIRONMENT = \ LD_LIBRARY_PATH=$(top_builddir)/src/.libs \ @@ -60,15 +60,19 @@ bindtests: bindtests.ml mlguestfs.cmxa $(OCAMLFIND) ocamlopt -cclib -L$(top_builddir)/src/.libs -I . unix.cmxa mlguestfs.cmxa $< -o $@ t/guestfs_005_load: t/guestfs_005_load.ml mlguestfs.cmxa + mkdir -p t $(OCAMLFIND) ocamlopt -cclib -L$(top_builddir)/src/.libs -I . unix.cmxa mlguestfs.cmxa $< -o $@ t/guestfs_010_launch: t/guestfs_010_launch.ml mlguestfs.cmxa + mkdir -p t $(OCAMLFIND) ocamlopt -cclib -L$(top_builddir)/src/.libs -I . unix.cmxa mlguestfs.cmxa $< -o $@ t/guestfs_050_lvcreate: t/guestfs_050_lvcreate.ml mlguestfs.cmxa + mkdir -p t $(OCAMLFIND) ocamlopt -cclib -L$(top_builddir)/src/.libs -I . unix.cmxa mlguestfs.cmxa $< -o $@ t/guestfs_060_readdir: t/guestfs_060_readdir.ml mlguestfs.cmxa + mkdir -p t $(OCAMLFIND) ocamlopt -cclib -L$(top_builddir)/src/.libs -I . unix.cmxa mlguestfs.cmxa $< -o $@ .mli.cmi: diff --git a/perl/Makefile.PL.in b/perl/Makefile.PL.in index 40d1d6c..d18aba6 100644 --- a/perl/Makefile.PL.in +++ b/perl/Makefile.PL.in @@ -23,7 +23,8 @@ WriteMakefile ( NAME => 'Sys::Guestfs', VERSION => '@PACKAGE_VERSION@', - LIBS => '-L@abs_top_builddir@/src/.libs -lguestfs', - INC => '-I@abs_top_builddir@/src', + LIBS => '-L@top_builddir@/src/.libs -lguestfs', + INC => '-I@top_builddir@/src -I@top_srcdir@/src', + TYPEMAPS => [ '@srcdir@/typemap' ], CCFLAGS => '@CFLAGS@', ); diff --git a/perl/Makefile.am b/perl/Makefile.am index 747ac43..66d1d4b 100644 --- a/perl/Makefile.am +++ b/perl/Makefile.am @@ -36,8 +36,8 @@ if HAVE_PERL TESTS = run-bindtests run-perl-tests TESTS_ENVIRONMENT = \ - LD_LIBRARY_PATH=../src/.libs \ - LIBGUESTFS_PATH=../appliance + LD_LIBRARY_PATH=$(top_builddir)/src/.libs \ + LIBGUESTFS_PATH=$(top_builddir)/appliance INSTALLDIRS = site diff --git a/python/Makefile.am b/python/Makefile.am index dcd0625..2928f98 100644 --- a/python/Makefile.am +++ b/python/Makefile.am @@ -32,12 +32,13 @@ python_DATA = guestfs.py python_LTLIBRARIES = libguestfsmod.la libguestfsmod_la_SOURCES = guestfs-py.c -libguestfsmod_la_CFLAGS = -Wall -I$(PYTHON_INCLUDEDIR) -I$(top_builddir)/src +libguestfsmod_la_CFLAGS = -Wall -I$(PYTHON_INCLUDEDIR) \ + -I$(top_srcdir)/src -I$(top_builddir)/src libguestfsmod_la_LIBADD = $(top_builddir)/src/libguestfs.la TESTS_ENVIRONMENT = \ LIBGUESTFS_PATH=$(top_builddir)/appliance \ - PYTHONPATH=$(top_builddir)/python:$(top_builddir)/python/.libs + PYTHONPATH=$(builddir):$(builddir)/.libs TESTS = run-bindtests run-python-tests diff --git a/recipes/clone.example b/recipes/clone.example index 40b4df1..3ee96c5 100644 --- a/recipes/clone.example +++ b/recipes/clone.example @@ -11,7 +11,7 @@ editing virtual machine filesystems. Type: 'help' for help with commands 'quit' to quit the shell -> cat /etc/resolv.conf +> cat /etc/resolv.conf nameserver 192.168.1.1 > cat /etc/HOSTNAME newmachine diff --git a/recipes/export2tar.example b/recipes/export2tar.example index 47033c8..7f222f3 100644 --- a/recipes/export2tar.example +++ b/recipes/export2tar.example @@ -1,8 +1,8 @@ $ ./export2tar.sh /dev/mapper/Guests-RHEL53PV32 /dev/VolGroup00/LogVol00 \ /home /tmp/home.tar.gz -$ ll /tmp/home.tar.gz +$ ll /tmp/home.tar.gz -rw-rw-r--. 1 rjones rjones 824 2009-04-25 12:33 /tmp/home.tar.gz -$ tar ztf /tmp/home.tar.gz +$ tar ztf /tmp/home.tar.gz ./ ./rjones/ ./rjones/.bash_profile diff --git a/recipes/iso2tar.example b/recipes/iso2tar.example index 16cb7da..5c796e1 100644 --- a/recipes/iso2tar.example +++ b/recipes/iso2tar.example @@ -1,4 +1,4 @@ -$ ll -h /tmp/Fedora-11-Beta-i386-netinst.iso +$ ll -h /tmp/Fedora-11-Beta-i386-netinst.iso -r--r--r--. 1 rjones rjones 168M 2009-04-25 22:38 /tmp/Fedora-11-Beta-i386-netinst.iso $ ./iso2tar.sh /tmp/Fedora-11-Beta-i386-netinst.iso /tmp/cd.tar.gz $ ls -lh /tmp/cd.tar.gz diff --git a/regressions/Makefile.am b/regressions/Makefile.am index 78ecfaa..2e1cb41 100644 --- a/regressions/Makefile.am +++ b/regressions/Makefile.am @@ -24,8 +24,23 @@ TESTS = \ rhbz503169c10.sh \ rhbz503169c13.sh \ + test-cancellation-upload-daemoncancels.sh \ + test-cancellation-download-librarycancels.sh \ + test-qemudie-midcommand.sh \ + test-qemudie-killsub.sh \ + test-qemudie-synch.sh + +SKIPPED_TESTS = \ test-bootbootboot.sh +FAILING_TESTS = \ + test-qemudie-launchfail.sh + +TESTS_ENVIRONMENT = \ + LD_LIBRARY_PATH=$(top_builddir)/src/.libs \ + LIBGUESTFS_PATH=$(top_builddir)/appliance + EXTRA_DIST = \ - test-cleanup.sh \ + $(FAILING_TESTS) \ + $(SKIPPED_TESTS) \ $(TESTS) diff --git a/regressions/rhbz503169c10.sh b/regressions/rhbz503169c10.sh index 8cdad50..2cfdbca 100755 --- a/regressions/rhbz503169c10.sh +++ b/regressions/rhbz503169c10.sh @@ -24,8 +24,6 @@ set -e rm -f test1.img dd if=/dev/zero of=test1.img bs=1024k count=10 -export LIBGUESTFS_PATH=../appliance - ../fish/guestfish -a test1.img < test.pid +! sleep 2 ; kill $(cat test.pid) & + +echo "Expect: 'guestfs_sleep reply failed, see earlier error messages'" +-sleep 1000 + +# We should now be able to rerun the subprocess. +run +ping-daemon +EOF + +rm -f test.pid test.img diff --git a/regressions/test-qemudie-synch.sh b/regressions/test-qemudie-synch.sh new file mode 100755 index 0000000..96e879d --- /dev/null +++ b/regressions/test-qemudie-synch.sh @@ -0,0 +1,42 @@ +#!/bin/sh - +# 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. + +# Test if we can handle qemu death synchronously. + +set -e + +rm -f test.pid test.img + +../fish/guestfish <<'EOF' +alloc test.img 10M +run + +# Kill subprocess. +pid | cat > test.pid +! kill $(cat test.pid) ; sleep 2 + +# XXX The following sleep should NOT be necessary. +echo "Expect an error from the next command" +-sleep 1 + +# We should now be able to rerun the subprocess. +run +ping-daemon +EOF + +rm -f test.pid test.img diff --git a/ruby/Makefile.am b/ruby/Makefile.am index 389399f..7ea0107 100644 --- a/ruby/Makefile.am +++ b/ruby/Makefile.am @@ -40,10 +40,10 @@ if HAVE_RUBY TESTS = run-bindtests run-ruby-tests TESTS_ENVIRONMENT = \ - LD_LIBRARY_PATH=../src/.libs \ - LIBGUESTFS_PATH=../appliance + LD_LIBRARY_PATH=$(top_builddir)/src/.libs \ + LIBGUESTFS_PATH=$(top_builddir)/appliance all: rake build -endif \ No newline at end of file +endif diff --git a/ruby/Rakefile.in b/ruby/Rakefile.in index 67f6b17..400ea0f 100644 --- a/ruby/Rakefile.in +++ b/ruby/Rakefile.in @@ -24,26 +24,24 @@ require 'rake/gempackagetask' PKG_NAME='@PACKAGE_NAME@' PKG_VERSION='@PACKAGE_VERSION@' -EXT_CONF='ext/guestfs/extconf.rb' -MAKEFILE='ext/guestfs/Makefile' -GUESTFS_MODULE='ext/guestfs/_guestfs.so' -GUESTFS_SRC='ext/guestfs/_guestfs.c' +EXT_CONF='@srcdir@/ext/guestfs/extconf.rb' +MAKEFILE='@builddir@/ext/guestfs/Makefile' +GUESTFS_MODULE='@builddir@/ext/guestfs/_guestfs.so' +GUESTFS_SRC='@builddir@/ext/guestfs/_guestfs.c' -CLEAN.include [ "ext/**/*.o", GUESTFS_MODULE, - "ext/**/depend" ] +CLEAN.include [ "@builddir@/ext/**/*.o", GUESTFS_MODULE, + "@builddir@/ext/**/depend" ] -CLOBBER.include [ "config.save", "ext/**/mkmf.log", +CLOBBER.include [ "@builddir@/config.save", "@builddir@/ext/**/mkmf.log", MAKEFILE ] # Build locally file MAKEFILE => EXT_CONF do |t| - Dir::chdir(File::dirname(EXT_CONF)) do - unless sh "ruby #{File::basename(EXT_CONF)} --with-_guestfs-include=../../../src --with-_guestfs-lib=../../../src/.libs" - $stderr.puts "Failed to run extconf" - break - end - end + unless sh "top_srcdir=$(pwd)/@top_srcdir@; top_builddir=$(pwd)/@top_builddir@; cd #{File::dirname(EXT_CONF)}; ruby #{File::basename(EXT_CONF)} --with-_guestfs-include=$top_srcdir/src --with-_guestfs-lib=$top_builddir/src/.libs" + $stderr.puts "Failed to run extconf" + break + end end file GUESTFS_MODULE => [ MAKEFILE, GUESTFS_SRC ] do |t| Dir::chdir(File::dirname(EXT_CONF)) do diff --git a/src/Makefile.am b/src/Makefile.am index 1c0fa0a..9dc8e99 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -30,8 +30,10 @@ EXTRA_DIST = \ noinst_DATA = stamp-generator stamp-generator: generator.ml - mkdir -p $(top_srcdir)/perl/lib/Sys - cd .. && ocaml -warn-error A $(srcdir)/src/$< + mkdir -p $(top_builddir)/perl/lib/Sys + mkdir -p $(top_builddir)/ruby/ext/guestfs + mkdir -p $(top_builddir)/java/com/redhat/et/libguestfs + cd $(top_builddir) && ocaml -warn-error A ./src/$< guestfs_protocol.x: stamp-generator @@ -83,6 +85,8 @@ lib_LTLIBRARIES = libguestfs.la BUILT_SOURCES = \ guestfs_protocol.x \ + guestfs_protocol.c \ + guestfs_protocol.h \ guestfs-structs.h \ guestfs-actions.h \ guestfs-actions.c \ diff --git a/src/generator.ml b/src/generator.ml index ed5810b..e97472d 100755 --- a/src/generator.ml +++ b/src/generator.ml @@ -66,15 +66,16 @@ and ret = (* "RString" and "RStringList" are caller-frees. *) | RString of string | RStringList of string - (* Some limited tuples are possible: *) - | RIntBool of string * string - (* LVM PVs, VGs and LVs. *) - | RPVList of string - | RVGList of string - | RLVList of string - (* Stat buffers. *) - | RStat of string - | RStatVFS of string + (* "RStruct" is a function which returns a single named structure + * or an error indication (in C, a struct, and in other languages + * with varying representations, but usually very efficient). See + * after the function list below for the structures. + *) + | RStruct of string * string (* name of retval, name of struct *) + (* "RStructList" is a function which returns either a list/array + * of structures (could be zero-length), or an error indication. + *) + | RStructList of string * string (* name of retval, name of struct *) (* Key-value pairs of untyped strings. Turns into a hashtable or * dictionary in languages which support it. DON'T use this as a * general "bucket" for results. Prefer a stronger typed return @@ -83,8 +84,6 @@ and ret = * inefficient. Keys should be unique. NULLs are not permitted. *) | RHashtable of string - (* List of directory entries (the result of readdir(3)). *) - | RDirentList of string and args = argt list (* Function parameters, guestfs handle is implicit. *) @@ -121,7 +120,7 @@ type flags = | NotInDocs (* do not add this function to documentation *) let protocol_limit_warning = - "Because of the message protocol, there is a transfer limit + "Because of the message protocol, there is a transfer limit of somewhere between 2MB and 4MB. To transfer large files you should use FTP." @@ -281,12 +280,8 @@ let test_all_rets = [ "test0rconststring", RConstString "valout"; "test0rstring", RString "valout"; "test0rstringlist", RStringList "valout"; - "test0rintbool", RIntBool ("valout", "valout"); - "test0rpvlist", RPVList "valout"; - "test0rvglist", RVGList "valout"; - "test0rlvlist", RLVList "valout"; - "test0rstat", RStat "valout"; - "test0rstatvfs", RStatVFS "valout"; + "test0rstruct", RStruct ("valout", "lvm_pv"); + "test0rstructlist", RStructList ("valout", "lvm_pv"); "test0rhashtable", RHashtable "valout"; ] @@ -632,6 +627,15 @@ then this returns the compiled-in default value for memsize. For more information on the architecture of libguestfs, see L."); + ("get_pid", (RInt "pid", []), -1, [FishAlias "pid"], + [], + "get PID of qemu subprocess", + "\ +Return the process ID of the qemu subprocess. If there is no +qemu subprocess, then this will return an error. + +This is an internal call used for debugging and testing."); + ] (* daemon_functions are any functions which cause some action @@ -813,21 +817,21 @@ This returns a list of the logical volume device names See also C."); - ("pvs_full", (RPVList "physvols", []), 12, [], + ("pvs_full", (RStructList ("physvols", "lvm_pv"), []), 12, [], [], (* XXX how to test? *) "list the LVM physical volumes (PVs)", "\ List all the physical volumes detected. This is the equivalent of the L command. The \"full\" version includes all fields."); - ("vgs_full", (RVGList "volgroups", []), 13, [], + ("vgs_full", (RStructList ("volgroups", "lvm_vg"), []), 13, [], [], (* XXX how to test? *) "list the LVM volume groups (VGs)", "\ List all the volumes groups detected. This is the equivalent of the L command. The \"full\" version includes all fields."); - ("lvs_full", (RLVList "logvols", []), 14, [], + ("lvs_full", (RStructList ("logvols", "lvm_lv"), []), 14, [], [], (* XXX how to test? *) "list the LVM logical volumes (LVs)", "\ @@ -924,7 +928,7 @@ undefined. On success this returns the number of nodes in C, or C<0> if C evaluates to something which is not a nodeset."); - ("aug_defnode", (RIntBool ("nrnodes", "created"), [String "name"; String "expr"; String "val"]), 18, [], + ("aug_defnode", (RStruct ("nrnodescreated", "int_bool"), [String "name"; String "expr"; String "val"]), 18, [], [], (* XXX Augeas code needs tests. *) "define an Augeas node", "\ @@ -1478,7 +1482,7 @@ result into a list of lines. See also: C"); - ("stat", (RStat "statbuf", [String "path"]), 52, [], + ("stat", (RStruct ("statbuf", "stat"), [String "path"]), 52, [], [InitBasicFS, Always, TestOutputStruct ( [["touch"; "/new"]; ["stat"; "/new"]], [CompareWithInt ("size", 0)])], @@ -1488,7 +1492,7 @@ Returns file information for the given C. This is the same as the C system call."); - ("lstat", (RStat "statbuf", [String "path"]), 53, [], + ("lstat", (RStruct ("statbuf", "stat"), [String "path"]), 53, [], [InitBasicFS, Always, TestOutputStruct ( [["touch"; "/new"]; ["lstat"; "/new"]], [CompareWithInt ("size", 0)])], @@ -1502,7 +1506,7 @@ refers to. This is the same as the C system call."); - ("statvfs", (RStatVFS "statbuf", [String "path"]), 54, [], + ("statvfs", (RStruct ("statbuf", "statvfs"), [String "path"]), 54, [], [InitBasicFS, Always, TestOutputStruct ( [["statvfs"; "/"]], [CompareWithInt ("namemax", 255); CompareWithInt ("bsize", 1024)])], @@ -2753,7 +2757,7 @@ See also L, C, C. This call returns the previous umask."); - ("readdir", (RDirentList "entries", [String "dir"]), 138, [], + ("readdir", (RStructList ("entries", "dirent"), [String "dir"]), 138, [], [], "read directories entries", "\ @@ -2790,107 +2794,153 @@ let all_functions_sorted = List.sort (fun (n1,_,_,_,_,_,_) (n2,_,_,_,_,_,_) -> compare n1 n2) all_functions -(* Column names and types from LVM PVs/VGs/LVs. *) -let pv_cols = [ - "pv_name", `String; - "pv_uuid", `UUID; - "pv_fmt", `String; - "pv_size", `Bytes; - "dev_size", `Bytes; - "pv_free", `Bytes; - "pv_used", `Bytes; - "pv_attr", `String (* XXX *); - "pv_pe_count", `Int; - "pv_pe_alloc_count", `Int; - "pv_tags", `String; - "pe_start", `Bytes; - "pv_mda_count", `Int; - "pv_mda_free", `Bytes; -(* Not in Fedora 10: - "pv_mda_size", `Bytes; -*) +(* Field types for structures. *) +type field = + | FChar (* C 'char' (really, a 7 bit byte). *) + | FString (* nul-terminated ASCII string. *) + | FUInt32 + | FInt32 + | FUInt64 + | FInt64 + | FBytes (* Any int measure that counts bytes. *) + | FUUID (* 32 bytes long, NOT nul-terminated. *) + | FOptPercent (* [0..100], or -1 meaning "not present". *) + +(* Because we generate extra parsing code for LVM command line tools, + * we have to pull out the LVM columns separately here. + *) +let lvm_pv_cols = [ + "pv_name", FString; + "pv_uuid", FUUID; + "pv_fmt", FString; + "pv_size", FBytes; + "dev_size", FBytes; + "pv_free", FBytes; + "pv_used", FBytes; + "pv_attr", FString (* XXX *); + "pv_pe_count", FInt64; + "pv_pe_alloc_count", FInt64; + "pv_tags", FString; + "pe_start", FBytes; + "pv_mda_count", FInt64; + "pv_mda_free", FBytes; + (* Not in Fedora 10: + "pv_mda_size", FBytes; + *) ] -let vg_cols = [ - "vg_name", `String; - "vg_uuid", `UUID; - "vg_fmt", `String; - "vg_attr", `String (* XXX *); - "vg_size", `Bytes; - "vg_free", `Bytes; - "vg_sysid", `String; - "vg_extent_size", `Bytes; - "vg_extent_count", `Int; - "vg_free_count", `Int; - "max_lv", `Int; - "max_pv", `Int; - "pv_count", `Int; - "lv_count", `Int; - "snap_count", `Int; - "vg_seqno", `Int; - "vg_tags", `String; - "vg_mda_count", `Int; - "vg_mda_free", `Bytes; -(* Not in Fedora 10: - "vg_mda_size", `Bytes; -*) +let lvm_vg_cols = [ + "vg_name", FString; + "vg_uuid", FUUID; + "vg_fmt", FString; + "vg_attr", FString (* XXX *); + "vg_size", FBytes; + "vg_free", FBytes; + "vg_sysid", FString; + "vg_extent_size", FBytes; + "vg_extent_count", FInt64; + "vg_free_count", FInt64; + "max_lv", FInt64; + "max_pv", FInt64; + "pv_count", FInt64; + "lv_count", FInt64; + "snap_count", FInt64; + "vg_seqno", FInt64; + "vg_tags", FString; + "vg_mda_count", FInt64; + "vg_mda_free", FBytes; + (* Not in Fedora 10: + "vg_mda_size", FBytes; + *) ] -let lv_cols = [ - "lv_name", `String; - "lv_uuid", `UUID; - "lv_attr", `String (* XXX *); - "lv_major", `Int; - "lv_minor", `Int; - "lv_kernel_major", `Int; - "lv_kernel_minor", `Int; - "lv_size", `Bytes; - "seg_count", `Int; - "origin", `String; - "snap_percent", `OptPercent; - "copy_percent", `OptPercent; - "move_pv", `String; - "lv_tags", `String; - "mirror_log", `String; - "modules", `String; +let lvm_lv_cols = [ + "lv_name", FString; + "lv_uuid", FUUID; + "lv_attr", FString (* XXX *); + "lv_major", FInt64; + "lv_minor", FInt64; + "lv_kernel_major", FInt64; + "lv_kernel_minor", FInt64; + "lv_size", FBytes; + "seg_count", FInt64; + "origin", FString; + "snap_percent", FOptPercent; + "copy_percent", FOptPercent; + "move_pv", FString; + "lv_tags", FString; + "mirror_log", FString; + "modules", FString; ] -(* Column names and types from stat structures. - * NB. Can't use things like 'st_atime' because glibc header files - * define some of these as macros. Ugh. +(* Names and fields in all structures (in RStruct and RStructList) + * that we support. *) -let stat_cols = [ - "dev", `Int; - "ino", `Int; - "mode", `Int; - "nlink", `Int; - "uid", `Int; - "gid", `Int; - "rdev", `Int; - "size", `Int; - "blksize", `Int; - "blocks", `Int; - "atime", `Int; - "mtime", `Int; - "ctime", `Int; -] -let statvfs_cols = [ - "bsize", `Int; - "frsize", `Int; - "blocks", `Int; - "bfree", `Int; - "bavail", `Int; - "files", `Int; - "ffree", `Int; - "favail", `Int; - "fsid", `Int; - "flag", `Int; - "namemax", `Int; -] - -(* Column names in dirent structure. *) -let dirent_cols = [ - "ino", `Int; - "ftyp", `Char; (* 'b' 'c' 'd' 'f' (FIFO) 'l' 'r' (regular file) 's' 'u' '?' *) - "name", `String; +let structs = [ + (* The old RIntBool return type, only ever used for aug_defnode. Do + * not use this struct in any new code. + *) + "int_bool", [ + "i", FInt32; (* for historical compatibility *) + "b", FInt32; (* for historical compatibility *) + ]; + + (* LVM PVs, VGs, LVs. *) + "lvm_pv", lvm_pv_cols; + "lvm_vg", lvm_vg_cols; + "lvm_lv", lvm_lv_cols; + + (* Column names and types from stat structures. + * NB. Can't use things like 'st_atime' because glibc header files + * define some of these as macros. Ugh. + *) + "stat", [ + "dev", FInt64; + "ino", FInt64; + "mode", FInt64; + "nlink", FInt64; + "uid", FInt64; + "gid", FInt64; + "rdev", FInt64; + "size", FInt64; + "blksize", FInt64; + "blocks", FInt64; + "atime", FInt64; + "mtime", FInt64; + "ctime", FInt64; + ]; + "statvfs", [ + "bsize", FInt64; + "frsize", FInt64; + "blocks", FInt64; + "bfree", FInt64; + "bavail", FInt64; + "files", FInt64; + "ffree", FInt64; + "favail", FInt64; + "fsid", FInt64; + "flag", FInt64; + "namemax", FInt64; + ]; + + (* Column names in dirent structure. *) + "dirent", [ + "ino", FInt64; + (* 'b' 'c' 'd' 'f' (FIFO) 'l' 'r' (regular file) 's' 'u' '?' *) + "ftyp", FChar; + "name", FString; + ]; +] (* end of structs *) + +(* Ugh, Java has to be different .. + * These names are also used by the Haskell bindings. + *) +let java_structs = [ + "int_bool", "IntBool"; + "lvm_pv", "PV"; + "lvm_vg", "VG"; + "lvm_lv", "LV"; + "stat", "Stat"; + "statvfs", "StatVFS"; + "dirent", "Dirent" ] (* Used for testing language bindings. *) @@ -3027,6 +3077,17 @@ let name_of_argt = function | String n | OptString n | StringList n | Bool n | Int n | FileIn n | FileOut n -> n +let java_name_of_struct typ = + try List.assoc typ java_structs + with Not_found -> + failwithf + "java_name_of_struct: no java_structs entry corresponding to %s" typ + +let cols_of_struct typ = + try List.assoc typ structs + with Not_found -> + failwithf "cols_of_struct: unknown struct %s" typ + let seq_of_test = function | TestRun s | TestOutput (s, _) | TestOutputList (s, _) | TestOutputListOfDevices (s, _) @@ -3086,14 +3147,9 @@ let check_functions () = (match fst style with | RErr -> () | RInt n | RInt64 n | RBool n | RConstString n | RString n - | RStringList n | RPVList n | RVGList n | RLVList n - | RStat n | RStatVFS n - | RHashtable n - | RDirentList n -> + | RStringList n | RStruct (n, _) | RStructList (n, _) + | RHashtable n -> check_arg_ret_name n - | RIntBool (n,m) -> - check_arg_ret_name n; - check_arg_ret_name m ); List.iter (fun arg -> check_arg_ret_name (name_of_argt arg)) (snd style) ) all_functions; @@ -3259,46 +3315,21 @@ I.\n\n" pr "This function returns a NULL-terminated array of strings (like L), or NULL if there was an error. I.\n\n" - | RIntBool _ -> - pr "This function returns a C, + | RStruct (_, typ) -> + pr "This function returns a C, or NULL if there was an error. -I after use>.\n\n" - | RPVList _ -> - pr "This function returns a C +I after use>.\n\n" typ typ + | RStructList (_, typ) -> + pr "This function returns a C (see Eguestfs-structs.hE), or NULL if there was an error. -I after use>.\n\n" - | RVGList _ -> - pr "This function returns a C -(see Eguestfs-structs.hE), -or NULL if there was an error. -I after use>.\n\n" - | RLVList _ -> - pr "This function returns a C -(see Eguestfs-structs.hE), -or NULL if there was an error. -I after use>.\n\n" - | RStat _ -> - pr "This function returns a C -(see L and Eguestfs-structs.hE), -or NULL if there was an error. -I after use>.\n\n" - | RStatVFS _ -> - pr "This function returns a C -(see L and Eguestfs-structs.hE), -or NULL if there was an error. -I after use>.\n\n" +I after use>.\n\n" typ typ | RHashtable _ -> pr "This function returns a NULL-terminated array of strings, or NULL if there was an error. The array of strings will always have length C<2n+1>, where C keys and values alternate, followed by the trailing NULL entry. I.\n\n" - | RDirentList _ -> - pr "This function returns a C -(see Eguestfs-structs.hE), -or NULL if there was an error. -I after use>.\n\n" ); if List.mem ProtocolLimitWarning flags then pr "%s\n\n" protocol_limit_warning; @@ -3308,68 +3339,39 @@ I after use>.\n\n" ) all_functions_sorted and generate_structs_pod () = - (* LVM structs documentation. *) + (* Structs documentation. *) List.iter ( fun (typ, cols) -> - pr "=head2 guestfs_lvm_%s\n" typ; + pr "=head2 guestfs_%s\n" typ; pr "\n"; - pr " struct guestfs_lvm_%s {\n" typ; + pr " struct guestfs_%s {\n" typ; List.iter ( function - | name, `String -> pr " char *%s;\n" name - | name, `UUID -> - pr " /* The next field is NOT nul-terminated, be careful when printing it: */\n"; - pr " char %s[32];\n" name - | name, `Bytes -> pr " uint64_t %s;\n" name - | name, `Int -> pr " int64_t %s;\n" name - | name, `OptPercent -> - pr " /* The next field is [0..100] or -1 meaning 'not present': */\n"; - pr " float %s;\n" name + | name, FChar -> pr " char %s;\n" name + | name, FUInt32 -> pr " uint32_t %s;\n" name + | name, FInt32 -> pr " int32_t %s;\n" name + | name, (FUInt64|FBytes) -> pr " uint64_t %s;\n" name + | name, FInt64 -> pr " int64_t %s;\n" name + | name, FString -> pr " char *%s;\n" name + | name, FUUID -> + pr " /* The next field is NOT nul-terminated, be careful when printing it: */\n"; + pr " char %s[32];\n" name + | name, FOptPercent -> + pr " /* The next field is [0..100] or -1 meaning 'not present': */\n"; + pr " float %s;\n" name ) cols; + pr " };\n"; pr " \n"; - pr " struct guestfs_lvm_%s_list {\n" typ; + pr " struct guestfs_%s_list {\n" typ; pr " uint32_t len; /* Number of elements in list. */\n"; - pr " struct guestfs_lvm_%s *val; /* Elements. */\n" typ; + pr " struct guestfs_%s *val; /* Elements. */\n" typ; pr " };\n"; pr " \n"; - pr " void guestfs_free_lvm_%s_list (struct guestfs_free_lvm_%s_list *);\n" + pr " void guestfs_free_%s (struct guestfs_free_%s *);\n" typ typ; + pr " void guestfs_free_%s_list (struct guestfs_free_%s_list *);\n" typ typ; pr "\n" - ) ["pv", pv_cols; "vg", vg_cols; "lv", lv_cols]; - - (* Stat *) - List.iter ( - fun (typ, cols) -> - pr "=head2 guestfs_%s\n" typ; - pr "\n"; - pr " struct guestfs_%s {\n" typ; - List.iter ( - function - | name, `Int -> pr " int64_t %s;\n" name - ) cols; - pr " };\n"; - pr "\n"; - ) [ "stat", stat_cols; "statvfs", statvfs_cols ]; - - (* DirentList *) - pr "=head2 guestfs_dirent\n"; - pr "\n"; - pr " struct guestfs_dirent {\n"; - List.iter ( - function - | name, `String -> pr " char *%s;\n" name - | name, `Int -> pr " int64_t %s;\n" name - | name, `Char -> pr " char %s;\n" name - ) dirent_cols; - pr " };\n"; - pr "\n"; - pr " struct guestfs_dirent_list {\n"; - pr " uint32_t len; /* Number of elements in list. */\n"; - pr " struct guestfs_dirent *val; /* Elements. */\n"; - pr " };\n"; - pr " \n"; - pr " void guestfs_free_dirent_list (struct guestfs_free_dirent_list *);\n"; - pr "\n" + ) structs (* Generate the protocol (XDR) file, 'guestfs_protocol.x' and * indirectly 'guestfs_protocol.h' and 'guestfs_protocol.c'. @@ -3386,47 +3388,24 @@ and generate_xdr () = pr "typedef string str<>;\n"; pr "\n"; - (* LVM internal structures. *) - List.iter ( - function - | typ, cols -> - pr "struct guestfs_lvm_int_%s {\n" typ; - List.iter (function - | name, `String -> pr " string %s<>;\n" name - | name, `UUID -> pr " opaque %s[32];\n" name - | name, `Bytes -> pr " hyper %s;\n" name - | name, `Int -> pr " hyper %s;\n" name - | name, `OptPercent -> pr " float %s;\n" name - ) cols; - pr "};\n"; - pr "\n"; - pr "typedef struct guestfs_lvm_int_%s guestfs_lvm_int_%s_list<>;\n" typ typ; - pr "\n"; - ) ["pv", pv_cols; "vg", vg_cols; "lv", lv_cols]; - - (* Stat internal structures. *) + (* Internal structures. *) List.iter ( function | typ, cols -> pr "struct guestfs_int_%s {\n" typ; List.iter (function - | name, `Int -> pr " hyper %s;\n" name + | name, FChar -> pr " char %s;\n" name + | name, FString -> pr " string %s<>;\n" name + | name, FUUID -> pr " opaque %s[32];\n" name + | name, (FInt32|FUInt32) -> pr " int %s;\n" name + | name, (FInt64|FUInt64|FBytes) -> pr " hyper %s;\n" name + | name, FOptPercent -> pr " float %s;\n" name ) cols; pr "};\n"; pr "\n"; - ) ["stat", stat_cols; "statvfs", statvfs_cols]; - - (* Dirent structures. *) - pr "struct guestfs_int_dirent {\n"; - List.iter (function - | name, `Int -> pr " hyper %s;\n" name - | name, `Char -> pr " char %s;\n" name - | name, `String -> pr " string %s<>;\n" name - ) dirent_cols; - pr "};\n"; - pr "\n"; - pr "typedef struct guestfs_int_dirent guestfs_int_dirent_list<>;\n"; - pr "\n"; + pr "typedef struct guestfs_int_%s guestfs_int_%s_list<>;\n" typ typ; + pr "\n"; + ) structs; List.iter ( fun (shortname, style, _, _, _, _, _) -> @@ -3471,39 +3450,18 @@ and generate_xdr () = pr "struct %s_ret {\n" name; pr " str %s<>;\n" n; pr "};\n\n" - | RIntBool (n,m) -> - pr "struct %s_ret {\n" name; - pr " int %s;\n" n; - pr " bool %s;\n" m; - pr "};\n\n" - | RPVList n -> - pr "struct %s_ret {\n" name; - pr " guestfs_lvm_int_pv_list %s;\n" n; - pr "};\n\n" - | RVGList n -> - pr "struct %s_ret {\n" name; - pr " guestfs_lvm_int_vg_list %s;\n" n; - pr "};\n\n" - | RLVList n -> - pr "struct %s_ret {\n" name; - pr " guestfs_lvm_int_lv_list %s;\n" n; - pr "};\n\n" - | RStat n -> + | RStruct (n, typ) -> pr "struct %s_ret {\n" name; - pr " guestfs_int_stat %s;\n" n; + pr " guestfs_int_%s %s;\n" typ n; pr "};\n\n" - | RStatVFS n -> + | RStructList (n, typ) -> pr "struct %s_ret {\n" name; - pr " guestfs_int_statvfs %s;\n" n; + pr " guestfs_int_%s_list %s;\n" typ n; pr "};\n\n" | RHashtable n -> pr "struct %s_ret {\n" name; pr " str %s<>;\n" n; pr "};\n\n" - | RDirentList n -> - pr "struct %s_ret {\n" name; - pr " guestfs_int_dirent_list %s;\n" n; - pr "};\n\n" ); ) daemon_functions; @@ -3591,63 +3549,32 @@ and generate_structs_h () = * must be identical to what rpcgen / the RFC defines. *) - (* guestfs_int_bool structure. *) - pr "struct guestfs_int_bool {\n"; - pr " int32_t i;\n"; - pr " int32_t b;\n"; - pr "};\n"; - pr "\n"; - - (* LVM public structures. *) + (* Public structures. *) List.iter ( - function - | typ, cols -> - pr "struct guestfs_lvm_%s {\n" typ; - List.iter ( - function - | name, `String -> pr " char *%s;\n" name - | name, `UUID -> pr " char %s[32]; /* this is NOT nul-terminated, be careful when printing */\n" name - | name, `Bytes -> pr " uint64_t %s;\n" name - | name, `Int -> pr " int64_t %s;\n" name - | name, `OptPercent -> pr " float %s; /* [0..100] or -1 */\n" name - ) cols; - pr "};\n"; - pr "\n"; - pr "struct guestfs_lvm_%s_list {\n" typ; - pr " uint32_t len;\n"; - pr " struct guestfs_lvm_%s *val;\n" typ; - pr "};\n"; - pr "\n" - ) ["pv", pv_cols; "vg", vg_cols; "lv", lv_cols]; - - (* Stat structures. *) - List.iter ( - function - | typ, cols -> - pr "struct guestfs_%s {\n" typ; - List.iter ( - function - | name, `Int -> pr " int64_t %s;\n" name - ) cols; - pr "};\n"; - pr "\n" - ) ["stat", stat_cols; "statvfs", statvfs_cols]; - - (* Dirent structures. *) - pr "struct guestfs_dirent {\n"; - List.iter ( - function - | name, `Int -> pr " int64_t %s;\n" name - | name, `Char -> pr " char %s;\n" name - | name, `String -> pr " char *%s;\n" name - ) dirent_cols; - pr "};\n"; - pr "\n"; - pr "struct guestfs_dirent_list {\n"; - pr " uint32_t len;\n"; - pr " struct guestfs_dirent *val;\n"; - pr "};\n"; - pr "\n" + fun (typ, cols) -> + pr "struct guestfs_%s {\n" typ; + List.iter ( + function + | name, FChar -> pr " char %s;\n" name + | name, FString -> pr " char *%s;\n" name + | name, FUUID -> pr " char %s[32]; /* this is NOT nul-terminated, be careful when printing */\n" name + | name, FUInt32 -> pr " uint32_t %s;\n" name + | name, FInt32 -> pr " int32_t %s;\n" name + | name, (FUInt64|FBytes) -> pr " uint64_t %s;\n" name + | name, FInt64 -> pr " int64_t %s;\n" name + | name, FOptPercent -> pr " float %s; /* [0..100] or -1 */\n" name + ) cols; + pr "};\n"; + pr "\n"; + pr "struct guestfs_%s_list {\n" typ; + pr " uint32_t len;\n"; + pr " struct guestfs_%s *val;\n" typ; + pr "};\n"; + pr "\n"; + pr "extern void guestfs_free_%s (struct guestfs_%s *);\n" typ typ; + pr "extern void guestfs_free_%s_list (struct guestfs_%s_list *);\n" typ typ; + pr "\n" + ) structs (* Generate the guestfs-actions.h file. *) and generate_actions_h () = @@ -3752,11 +3679,8 @@ check_state (guestfs_h *g, const char *caller) failwithf "RConstString cannot be returned from a daemon function" | RInt _ | RInt64 _ | RBool _ | RString _ | RStringList _ - | RIntBool _ - | RPVList _ | RVGList _ | RLVList _ - | RStat _ | RStatVFS _ - | RHashtable _ - | RDirentList _ -> + | RStruct _ | RStructList _ + | RHashtable _ -> pr " struct %s_ret ret;\n" name ); pr "};\n"; @@ -3796,11 +3720,8 @@ check_state (guestfs_h *g, const char *caller) failwithf "RConstString cannot be returned from a daemon function" | RInt _ | RInt64 _ | RBool _ | RString _ | RStringList _ - | RIntBool _ - | RPVList _ | RVGList _ | RLVList _ - | RStat _ | RStatVFS _ - | RHashtable _ - | RDirentList _ -> + | RStruct _ | RStructList _ + | RHashtable _ -> pr " if (!xdr_%s_ret (xdr, &ctx->ret)) {\n" name; pr " error (g, \"%%s: failed to parse reply\", \"%s\");\n" name; pr " return;\n"; @@ -3820,11 +3741,9 @@ check_state (guestfs_h *g, const char *caller) | RErr | RInt _ | RInt64 _ | RBool _ -> "-1" | RConstString _ -> failwithf "RConstString cannot be returned from a daemon function" - | RString _ | RStringList _ | RIntBool _ - | RPVList _ | RVGList _ | RLVList _ - | RStat _ | RStatVFS _ - | RHashtable _ - | RDirentList _ -> + | RString _ | RStringList _ + | RStruct _ | RStructList _ + | RHashtable _ -> "NULL" in pr "{\n"; @@ -3956,18 +3875,43 @@ check_state (guestfs_h *g, const char *caller) n n; pr " ctx.ret.%s.%s_val[ctx.ret.%s.%s_len] = NULL;\n" n n n n; pr " return ctx.ret.%s.%s_val;\n" n n - | RIntBool _ -> - pr " /* caller with free this */\n"; - pr " return safe_memdup (g, &ctx.ret, sizeof (ctx.ret));\n" - | RPVList n | RVGList n | RLVList n - | RStat n | RStatVFS n - | RDirentList n -> + | RStruct (n, _) -> + pr " /* caller will free this */\n"; + pr " return safe_memdup (g, &ctx.ret.%s, sizeof (ctx.ret.%s));\n" n n + | RStructList (n, _) -> pr " /* caller will free this */\n"; pr " return safe_memdup (g, &ctx.ret.%s, sizeof (ctx.ret.%s));\n" n n ); pr "}\n\n" - ) daemon_functions + ) daemon_functions; + + (* Functions to free structures. *) + pr "/* Structure-freeing functions. These rely on the fact that the\n"; + pr " * structure format is identical to the XDR format. See note in\n"; + pr " * generator.ml.\n"; + pr " */\n"; + pr "\n"; + + List.iter ( + fun (typ, _) -> + pr "void\n"; + pr "guestfs_free_%s (struct guestfs_%s *x)\n" typ typ; + pr "{\n"; + pr " xdr_free ((xdrproc_t) xdr_guestfs_int_%s, (char *) x);\n" typ; + pr " free (x);\n"; + pr "}\n"; + pr "\n"; + + pr "void\n"; + pr "guestfs_free_%s_list (struct guestfs_%s_list *x)\n" typ typ; + pr "{\n"; + pr " xdr_free ((xdrproc_t) xdr_guestfs_int_%s_list, (char *) x);\n" typ; + pr " free (x);\n"; + pr "}\n"; + pr "\n"; + + ) structs; (* Generate daemon/actions.h. *) and generate_daemon_actions_h () = @@ -4016,13 +3960,8 @@ and generate_daemon_actions () = failwithf "RConstString cannot be returned from a daemon function" | RString _ -> pr " char *r;\n"; "NULL" | RStringList _ | RHashtable _ -> pr " char **r;\n"; "NULL" - | RIntBool _ -> pr " guestfs_%s_ret *r;\n" name; "NULL" - | RPVList _ -> pr " guestfs_lvm_int_pv_list *r;\n"; "NULL" - | RVGList _ -> pr " guestfs_lvm_int_vg_list *r;\n"; "NULL" - | RLVList _ -> pr " guestfs_lvm_int_lv_list *r;\n"; "NULL" - | RStat _ -> pr " guestfs_int_stat *r;\n"; "NULL" - | RStatVFS _ -> pr " guestfs_int_statvfs *r;\n"; "NULL" - | RDirentList _ -> pr " guestfs_int_dirent_list *r;\n"; "NULL" in + | RStruct (_, typ) -> pr " guestfs_int_%s *r;\n" typ; "NULL" + | RStructList (_, typ) -> pr " guestfs_int_%s_list *r;\n" typ; "NULL" in (match snd style with | [] -> () @@ -4118,13 +4057,14 @@ and generate_daemon_actions () = pr " reply ((xdrproc_t) &xdr_guestfs_%s_ret, (char *) &ret);\n" name; pr " free_strings (r);\n" - | RIntBool _ -> - pr " reply ((xdrproc_t) xdr_guestfs_%s_ret, (char *) r);\n" + | RStruct (n, _) -> + pr " struct guestfs_%s_ret ret;\n" name; + pr " ret.%s = *r;\n" n; + pr " reply ((xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret);\n" name; - pr " xdr_free ((xdrproc_t) xdr_guestfs_%s_ret, (char *) r);\n" name - | RPVList n | RVGList n | RLVList n - | RStat n | RStatVFS n - | RDirentList n -> + pr " xdr_free ((xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret);\n" + name + | RStructList (n, _) -> pr " struct guestfs_%s_ret ret;\n" name; pr " ret.%s = *r;\n" n; pr " reply ((xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret);\n" @@ -4175,7 +4115,7 @@ and generate_daemon_actions () = typ (String.concat "," (List.map fst cols)); pr "\n"; - pr "static int lvm_tokenize_%s (char *str, struct guestfs_lvm_int_%s *r)\n" typ typ; + pr "static int lvm_tokenize_%s (char *str, guestfs_int_lvm_%s *r)\n" typ typ; pr "{\n"; pr " char *tok, *p, *next;\n"; pr " int i, j;\n"; @@ -4203,13 +4143,13 @@ and generate_daemon_actions () = pr " if (*p) next = p+1; else next = NULL;\n"; pr " *p = '\\0';\n"; (match coltype with - | `String -> + | FString -> pr " r->%s = strdup (tok);\n" name; pr " if (r->%s == NULL) {\n" name; pr " perror (\"strdup\");\n"; pr " return -1;\n"; pr " }\n" - | `UUID -> + | FUUID -> pr " for (i = j = 0; i < 32; ++j) {\n"; pr " if (tok[j] == '\\0') {\n"; pr " fprintf (stderr, \"%%s: failed to parse UUID from '%%s'\\n\", __func__, tok);\n"; @@ -4217,23 +4157,25 @@ and generate_daemon_actions () = pr " } else if (tok[j] != '-')\n"; pr " r->%s[i++] = tok[j];\n" name; pr " }\n"; - | `Bytes -> + | FBytes -> pr " if (sscanf (tok, \"%%\"SCNu64, &r->%s) != 1) {\n" name; pr " fprintf (stderr, \"%%s: failed to parse size '%%s' from token %%s\\n\", __func__, tok, \"%s\");\n" name; pr " return -1;\n"; pr " }\n"; - | `Int -> + | FInt64 -> pr " if (sscanf (tok, \"%%\"SCNi64, &r->%s) != 1) {\n" name; pr " fprintf (stderr, \"%%s: failed to parse int '%%s' from token %%s\\n\", __func__, tok, \"%s\");\n" name; pr " return -1;\n"; pr " }\n"; - | `OptPercent -> + | FOptPercent -> pr " if (tok[0] == '\\0')\n"; pr " r->%s = -1;\n" name; pr " else if (sscanf (tok, \"%%f\", &r->%s) != 1) {\n" name; pr " fprintf (stderr, \"%%s: failed to parse float '%%s' from token %%s\\n\", __func__, tok, \"%s\");\n" name; pr " return -1;\n"; pr " }\n"; + | FInt32 | FUInt32 | FUInt64 | FChar -> + assert false (* can never be an LVM column *) ); pr " tok = next;\n"; ) cols; @@ -4246,13 +4188,13 @@ and generate_daemon_actions () = pr "}\n"; pr "\n"; - pr "guestfs_lvm_int_%s_list *\n" typ; + pr "guestfs_int_lvm_%s_list *\n" typ; pr "parse_command_line_%ss (void)\n" typ; pr "{\n"; pr " char *out, *err;\n"; pr " char *p, *pend;\n"; pr " int r, i;\n"; - pr " guestfs_lvm_int_%s_list *ret;\n" typ; + pr " guestfs_int_lvm_%s_list *ret;\n" typ; pr " void *newp;\n"; pr "\n"; pr " ret = malloc (sizeof *ret);\n"; @@ -4261,8 +4203,8 @@ and generate_daemon_actions () = pr " return NULL;\n"; pr " }\n"; pr "\n"; - pr " ret->guestfs_lvm_int_%s_list_len = 0;\n" typ; - pr " ret->guestfs_lvm_int_%s_list_val = NULL;\n" typ; + pr " ret->guestfs_int_lvm_%s_list_len = 0;\n" typ; + pr " ret->guestfs_int_lvm_%s_list_val = NULL;\n" typ; pr "\n"; pr " r = command (&out, &err,\n"; pr " \"/sbin/lvm\", \"%ss\",\n" typ; @@ -4297,22 +4239,22 @@ and generate_daemon_actions () = pr " }\n"; pr "\n"; pr " /* Allocate some space to store this next entry. */\n"; - pr " newp = realloc (ret->guestfs_lvm_int_%s_list_val,\n" typ; - pr " sizeof (guestfs_lvm_int_%s) * (i+1));\n" typ; + pr " newp = realloc (ret->guestfs_int_lvm_%s_list_val,\n" typ; + pr " sizeof (guestfs_int_lvm_%s) * (i+1));\n" typ; pr " if (newp == NULL) {\n"; pr " reply_with_perror (\"realloc\");\n"; - pr " free (ret->guestfs_lvm_int_%s_list_val);\n" typ; + pr " free (ret->guestfs_int_lvm_%s_list_val);\n" typ; pr " free (ret);\n"; pr " free (out);\n"; pr " return NULL;\n"; pr " }\n"; - pr " ret->guestfs_lvm_int_%s_list_val = newp;\n" typ; + pr " ret->guestfs_int_lvm_%s_list_val = newp;\n" typ; pr "\n"; pr " /* Tokenize the next entry. */\n"; - pr " r = lvm_tokenize_%s (p, &ret->guestfs_lvm_int_%s_list_val[i]);\n" typ typ; + pr " r = lvm_tokenize_%s (p, &ret->guestfs_int_lvm_%s_list_val[i]);\n" typ typ; pr " if (r == -1) {\n"; pr " reply_with_error (\"failed to parse output of '%ss' command\");\n" typ; - pr " free (ret->guestfs_lvm_int_%s_list_val);\n" typ; + pr " free (ret->guestfs_int_lvm_%s_list_val);\n" typ; pr " free (ret);\n"; pr " free (out);\n"; pr " return NULL;\n"; @@ -4322,13 +4264,13 @@ and generate_daemon_actions () = pr " p = pend;\n"; pr " }\n"; pr "\n"; - pr " ret->guestfs_lvm_int_%s_list_len = i;\n" typ; + pr " ret->guestfs_int_lvm_%s_list_len = i;\n" typ; pr "\n"; pr " free (out);\n"; pr " return ret;\n"; pr "}\n" - ) ["pv", pv_cols; "vg", vg_cols; "lv", lv_cols] + ) ["pv", lvm_pv_cols; "vg", lvm_vg_cols; "lv", lvm_lv_cols] (* Generate a list of function names, for debugging in the daemon.. *) and generate_daemon_names () = @@ -4686,7 +4628,7 @@ and generate_one_test_body name i test_name init test = List.iter (generate_test_command_call test_name) seq | TestOutput (seq, expected) -> pr " /* TestOutput for %s (%d) */\n" name i; - pr " char expected[] = \"%s\";\n" (c_quote expected); + pr " const char *expected = \"%s\";\n" (c_quote expected); let seq, last = get_seq_last seq in let test () = pr " if (strcmp (r, expected) != 0) {\n"; @@ -4708,7 +4650,7 @@ and generate_one_test_body name i test_name init test = pr " return -1;\n"; pr " }\n"; pr " {\n"; - pr " char expected[] = \"%s\";\n" (c_quote str); + pr " const char *expected = \"%s\";\n" (c_quote str); pr " if (strcmp (r[%d], expected) != 0) {\n" i; pr " fprintf (stderr, \"%s: expected \\\"%%s\\\" but got \\\"%%s\\\"\\n\", expected, r[%d]);\n" test_name i; pr " return -1;\n"; @@ -4736,7 +4678,7 @@ and generate_one_test_body name i test_name init test = pr " return -1;\n"; pr " }\n"; pr " {\n"; - pr " char expected[] = \"%s\";\n" (c_quote str); + pr " const char *expected = \"%s\";\n" (c_quote str); pr " r[%d][5] = 's';\n" i; pr " if (strcmp (r[%d], expected) != 0) {\n" i; pr " fprintf (stderr, \"%s: expected \\\"%%s\\\" but got \\\"%%s\\\"\\n\", expected, r[%d]);\n" test_name i; @@ -4882,7 +4824,7 @@ and generate_test_command_call ?(expect_error = false) ?test test_name cmd = | OptString n, "NULL" -> () | String n, arg | OptString n, arg -> - pr " char %s[] = \"%s\";\n" n (c_quote arg); + pr " const char *%s = \"%s\";\n" n (c_quote arg); | Int _, _ | Bool _, _ | FileIn _, _ | FileOut _, _ -> () @@ -4890,9 +4832,9 @@ and generate_test_command_call ?(expect_error = false) ?test test_name cmd = let strs = string_split " " arg in iteri ( fun i str -> - pr " char %s_%d[] = \"%s\";\n" n i (c_quote str); + pr " const char *%s_%d = \"%s\";\n" n i (c_quote str); ) strs; - pr " char *%s[] = {\n" n; + pr " const char *%s[] = {\n" n; iteri ( fun i _ -> pr " %s_%d,\n" n i ) strs; @@ -4910,20 +4852,10 @@ and generate_test_command_call ?(expect_error = false) ?test test_name cmd = pr " char **r;\n"; pr " int i;\n"; "NULL" - | RIntBool _ -> - pr " struct guestfs_int_bool *r;\n"; "NULL" - | RPVList _ -> - pr " struct guestfs_lvm_pv_list *r;\n"; "NULL" - | RVGList _ -> - pr " struct guestfs_lvm_vg_list *r;\n"; "NULL" - | RLVList _ -> - pr " struct guestfs_lvm_lv_list *r;\n"; "NULL" - | RStat _ -> - pr " struct guestfs_stat *r;\n"; "NULL" - | RStatVFS _ -> - pr " struct guestfs_statvfs *r;\n"; "NULL" - | RDirentList _ -> - pr " struct guestfs_dirent_list *r;\n"; "NULL" in + | RStruct (_, typ) -> + pr " struct guestfs_%s *r;\n" typ; "NULL" + | RStructList (_, typ) -> + pr " struct guestfs_%s_list *r;\n" typ; "NULL" in pr " suppress_error = %d;\n" (if expect_error then 1 else 0); pr " r = guestfs_%s (g" name; @@ -4969,18 +4901,10 @@ and generate_test_command_call ?(expect_error = false) ?test test_name cmd = pr " for (i = 0; r[i] != NULL; ++i)\n"; pr " free (r[i]);\n"; pr " free (r);\n" - | RIntBool _ -> - pr " guestfs_free_int_bool (r);\n" - | RPVList _ -> - pr " guestfs_free_lvm_pv_list (r);\n" - | RVGList _ -> - pr " guestfs_free_lvm_vg_list (r);\n" - | RLVList _ -> - pr " guestfs_free_lvm_lv_list (r);\n" - | RStat _ | RStatVFS _ -> - pr " free (r);\n" - | RDirentList _ -> - pr " guestfs_free_dirent_list (r);\n" + | RStruct (_, typ) -> + pr " guestfs_free_%s (r);\n" typ + | RStructList (_, typ) -> + pr " guestfs_free_%s_list (r);\n" typ ); pr " }\n" @@ -5082,82 +5006,47 @@ and generate_fish_cmds () = pr "}\n"; pr "\n"; - (* print_{pv,vg,lv}_list functions *) - List.iter ( - function - | typ, cols -> - pr "static void print_%s (struct guestfs_lvm_%s *%s)\n" typ typ typ; - pr "{\n"; - pr " int i;\n"; - pr "\n"; - List.iter ( - function - | name, `String -> - pr " printf (\"%s: %%s\\n\", %s->%s);\n" name typ name - | name, `UUID -> - pr " printf (\"%s: \");\n" name; - pr " for (i = 0; i < 32; ++i)\n"; - pr " printf (\"%%c\", %s->%s[i]);\n" typ name; - pr " printf (\"\\n\");\n" - | name, `Bytes -> - pr " printf (\"%s: %%\" PRIu64 \"\\n\", %s->%s);\n" name typ name - | name, `Int -> - pr " printf (\"%s: %%\" PRIi64 \"\\n\", %s->%s);\n" name typ name - | name, `OptPercent -> - pr " if (%s->%s >= 0) printf (\"%s: %%g %%%%\\n\", %s->%s);\n" - typ name name typ name; - pr " else printf (\"%s: \\n\");\n" name - ) cols; - pr "}\n"; - pr "\n"; - pr "static void print_%s_list (struct guestfs_lvm_%s_list *%ss)\n" - typ typ typ; - pr "{\n"; - pr " int i;\n"; - pr "\n"; - pr " for (i = 0; i < %ss->len; ++i)\n" typ; - pr " print_%s (&%ss->val[i]);\n" typ typ; - pr "}\n"; - pr "\n"; - ) ["pv", pv_cols; "vg", vg_cols; "lv", lv_cols]; - - (* print_{stat,statvfs} functions *) - List.iter ( - function - | typ, cols -> - pr "static void print_%s (struct guestfs_%s *%s)\n" typ typ typ; - pr "{\n"; - List.iter ( - function - | name, `Int -> - pr " printf (\"%s: %%\" PRIi64 \"\\n\", %s->%s);\n" name typ name - ) cols; - pr "}\n"; - pr "\n"; - ) ["stat", stat_cols; "statvfs", statvfs_cols]; - - (* print_dirent_list function *) - pr "static void print_dirent (struct guestfs_dirent *dirent)\n"; - pr "{\n"; + (* print_* functions *) List.iter ( - function - | name, `String -> - pr " printf (\"%s: %%s\\n\", dirent->%s);\n" name name - | name, `Int -> - pr " printf (\"%s: %%\" PRIi64 \"\\n\", dirent->%s);\n" name name - | name, `Char -> - pr " printf (\"%s: %%c\\n\", dirent->%s);\n" name name - ) dirent_cols; - pr "}\n"; - pr "\n"; - pr "static void print_dirent_list (struct guestfs_dirent_list *dirents)\n"; - pr "{\n"; - pr " int i;\n"; - pr "\n"; - pr " for (i = 0; i < dirents->len; ++i)\n"; - pr " print_dirent (&dirents->val[i]);\n"; - pr "}\n"; - pr "\n"; + fun (typ, cols) -> + pr "static void print_%s (struct guestfs_%s *%s)\n" typ typ typ; + pr "{\n"; + List.iter ( + function + | name, FString -> + pr " printf (\"%s: %%s\\n\", %s->%s);\n" name typ name + | name, FUUID -> + pr " printf (\"%s: \");\n" name; + pr " for (int i = 0; i < 32; ++i)\n"; + pr " printf (\"%%c\", %s->%s[i]);\n" typ name; + pr " printf (\"\\n\");\n" + | name, (FUInt64|FBytes) -> + pr " printf (\"%s: %%\" PRIu64 \"\\n\", %s->%s);\n" name typ name + | name, FInt64 -> + pr " printf (\"%s: %%\" PRIi64 \"\\n\", %s->%s);\n" name typ name + | name, FUInt32 -> + pr " printf (\"%s: %%\" PRIu32 \"\\n\", %s->%s);\n" name typ name + | name, FInt32 -> + pr " printf (\"%s: %%\" PRIi32 \"\\n\", %s->%s);\n" name typ name + | name, FChar -> + pr " printf (\"%s: %%c\\n\", %s->%s);\n" name typ name + | name, FOptPercent -> + pr " if (%s->%s >= 0) printf (\"%s: %%g %%%%\\n\", %s->%s);\n" + typ name name typ name; + pr " else printf (\"%s: \\n\");\n" name + ) cols; + pr "}\n"; + pr "\n"; + pr "static void print_%s_list (struct guestfs_%s_list *%ss)\n" + typ typ typ; + pr "{\n"; + pr " int i;\n"; + pr "\n"; + pr " for (i = 0; i < %ss->len; ++i)\n" typ; + pr " print_%s (&%ss->val[i]);\n" typ typ; + pr "}\n"; + pr "\n"; + ) structs; (* run_ actions *) List.iter ( @@ -5172,13 +5061,8 @@ and generate_fish_cmds () = | RConstString _ -> pr " const char *r;\n" | RString _ -> pr " char *r;\n" | RStringList _ | RHashtable _ -> pr " char **r;\n" - | RIntBool _ -> pr " struct guestfs_int_bool *r;\n" - | RPVList _ -> pr " struct guestfs_lvm_pv_list *r;\n" - | RVGList _ -> pr " struct guestfs_lvm_vg_list *r;\n" - | RLVList _ -> pr " struct guestfs_lvm_lv_list *r;\n" - | RStat _ -> pr " struct guestfs_stat *r;\n" - | RStatVFS _ -> pr " struct guestfs_statvfs *r;\n" - | RDirentList _ -> pr " struct guestfs_dirent_list *r;\n" + | RStruct (_, typ) -> pr " struct guestfs_%s *r;\n" typ + | RStructList (_, typ) -> pr " struct guestfs_%s_list *r;\n" typ ); List.iter ( function @@ -5257,47 +5141,21 @@ and generate_fish_cmds () = pr " print_strings (r);\n"; pr " free_strings (r);\n"; pr " return 0;\n" - | RIntBool _ -> - pr " if (r == NULL) return -1;\n"; - pr " printf (\"%%d, %%s\\n\", r->i,\n"; - pr " r->b ? \"true\" : \"false\");\n"; - pr " guestfs_free_int_bool (r);\n"; - pr " return 0;\n" - | RPVList _ -> + | RStruct (_, typ) -> pr " if (r == NULL) return -1;\n"; - pr " print_pv_list (r);\n"; - pr " guestfs_free_lvm_pv_list (r);\n"; + pr " print_%s (r);\n" typ; + pr " guestfs_free_%s (r);\n" typ; pr " return 0;\n" - | RVGList _ -> + | RStructList (_, typ) -> pr " if (r == NULL) return -1;\n"; - pr " print_vg_list (r);\n"; - pr " guestfs_free_lvm_vg_list (r);\n"; - pr " return 0;\n" - | RLVList _ -> - pr " if (r == NULL) return -1;\n"; - pr " print_lv_list (r);\n"; - pr " guestfs_free_lvm_lv_list (r);\n"; - pr " return 0;\n" - | RStat _ -> - pr " if (r == NULL) return -1;\n"; - pr " print_stat (r);\n"; - pr " free (r);\n"; - pr " return 0;\n" - | RStatVFS _ -> - pr " if (r == NULL) return -1;\n"; - pr " print_statvfs (r);\n"; - pr " free (r);\n"; + pr " print_%s_list (r);\n" typ; + pr " guestfs_free_%s_list (r);\n" typ; pr " return 0;\n" | RHashtable _ -> pr " if (r == NULL) return -1;\n"; pr " print_table (r);\n"; pr " free_strings (r);\n"; pr " return 0;\n" - | RDirentList _ -> - pr " if (r == NULL) return -1;\n"; - pr " print_dirent_list (r);\n"; - pr " guestfs_free_dirent_list (r);\n"; - pr " return 0;\n" ); pr "}\n"; pr "\n" @@ -5490,27 +5348,12 @@ and generate_prototype ?(extern = true) ?(static = false) ?(semicolon = true) | RConstString _ -> pr "const char *" | RString _ -> pr "char *" | RStringList _ | RHashtable _ -> pr "char **" - | RIntBool _ -> - if not in_daemon then pr "struct guestfs_int_bool *" - else pr "guestfs_%s_ret *" name - | RPVList _ -> - if not in_daemon then pr "struct guestfs_lvm_pv_list *" - else pr "guestfs_lvm_int_pv_list *" - | RVGList _ -> - if not in_daemon then pr "struct guestfs_lvm_vg_list *" - else pr "guestfs_lvm_int_vg_list *" - | RLVList _ -> - if not in_daemon then pr "struct guestfs_lvm_lv_list *" - else pr "guestfs_lvm_int_lv_list *" - | RStat _ -> - if not in_daemon then pr "struct guestfs_stat *" - else pr "guestfs_int_stat *" - | RStatVFS _ -> - if not in_daemon then pr "struct guestfs_statvfs *" - else pr "guestfs_int_statvfs *" - | RDirentList _ -> - if not in_daemon then pr "struct guestfs_dirent_list *" - else pr "guestfs_int_dirent_list *" + | RStruct (_, typ) -> + if not in_daemon then pr "struct guestfs_%s *" typ + else pr "guestfs_int_%s *" typ + | RStructList (_, typ) -> + if not in_daemon then pr "struct guestfs_%s_list *" typ + else pr "guestfs_int_%s_list *" typ ); pr "%s%s (" prefix name; if handle = None && List.length (snd style) = 0 then @@ -5588,11 +5431,7 @@ val close : t -> unit provide predictable cleanup. *) "; - generate_ocaml_lvm_structure_decls (); - - generate_ocaml_stat_structure_decls (); - - generate_ocaml_dirent_structure_decls (); + generate_ocaml_structure_decls (); (* The actions. *) List.iter ( @@ -5617,11 +5456,7 @@ let () = "; - generate_ocaml_lvm_structure_decls (); - - generate_ocaml_stat_structure_decls (); - - generate_ocaml_dirent_structure_decls (); + generate_ocaml_structure_decls (); (* The actions. *) List.iter ( @@ -5679,14 +5514,14 @@ copy_table (char * const * argv) "; - (* LVM struct copy functions. *) + (* Struct copy functions. *) List.iter ( fun (typ, cols) -> let has_optpercent_col = - List.exists (function (_, `OptPercent) -> true | _ -> false) cols in + List.exists (function (_, FOptPercent) -> true | _ -> false) cols in pr "static CAMLprim value\n"; - pr "copy_lvm_%s (const struct guestfs_lvm_%s *%s)\n" typ typ typ; + pr "copy_%s (const struct guestfs_%s *%s)\n" typ typ typ; pr "{\n"; pr " CAMLparam0 ();\n"; if has_optpercent_col then @@ -5698,21 +5533,24 @@ copy_table (char * const * argv) iteri ( fun i col -> (match col with - | name, `String -> + | name, FString -> pr " v = caml_copy_string (%s->%s);\n" typ name - | name, `UUID -> + | name, FUUID -> pr " v = caml_alloc_string (32);\n"; pr " memcpy (String_val (v), %s->%s, 32);\n" typ name - | name, `Bytes - | name, `Int -> + | name, (FBytes|FInt64|FUInt64) -> pr " v = caml_copy_int64 (%s->%s);\n" typ name - | name, `OptPercent -> + | name, (FInt32|FUInt32) -> + pr " v = caml_copy_int32 (%s->%s);\n" typ name + | name, FOptPercent -> pr " if (%s->%s >= 0) { /* Some %s */\n" typ name name; pr " v2 = caml_copy_double (%s->%s);\n" typ name; pr " v = caml_alloc (1, 0);\n"; pr " Store_field (v, 0, v2);\n"; pr " } else /* None */\n"; pr " v = Val_int (0);\n"; + | name, FChar -> + pr " v = Val_int (%s->%s);\n" typ name ); pr " Store_field (rv, %d, v);\n" i ) cols; @@ -5721,7 +5559,7 @@ copy_table (char * const * argv) pr "\n"; pr "static CAMLprim value\n"; - pr "copy_lvm_%s_list (const struct guestfs_lvm_%s_list *%ss)\n" + pr "copy_%s_list (const struct guestfs_%s_list *%ss)\n" typ typ typ; pr "{\n"; pr " CAMLparam0 ();\n"; @@ -5733,81 +5571,14 @@ copy_table (char * const * argv) pr " else {\n"; pr " rv = caml_alloc (%ss->len, 0);\n" typ; pr " for (i = 0; i < %ss->len; ++i) {\n" typ; - pr " v = copy_lvm_%s (&%ss->val[i]);\n" typ typ; + pr " v = copy_%s (&%ss->val[i]);\n" typ typ; pr " caml_modify (&Field (rv, i), v);\n"; pr " }\n"; pr " CAMLreturn (rv);\n"; pr " }\n"; pr "}\n"; pr "\n"; - ) ["pv", pv_cols; "vg", vg_cols; "lv", lv_cols]; - - (* Stat copy functions. *) - List.iter ( - fun (typ, cols) -> - pr "static CAMLprim value\n"; - pr "copy_%s (const struct guestfs_%s *%s)\n" typ typ typ; - pr "{\n"; - pr " CAMLparam0 ();\n"; - pr " CAMLlocal2 (rv, v);\n"; - pr "\n"; - pr " rv = caml_alloc (%d, 0);\n" (List.length cols); - iteri ( - fun i col -> - (match col with - | name, `Int -> - pr " v = caml_copy_int64 (%s->%s);\n" typ name - ); - pr " Store_field (rv, %d, v);\n" i - ) cols; - pr " CAMLreturn (rv);\n"; - pr "}\n"; - pr "\n"; - ) ["stat", stat_cols; "statvfs", statvfs_cols]; - - (* Dirent copy functions. *) - pr "static CAMLprim value\n"; - pr "copy_dirent (const struct guestfs_dirent *dirent)\n"; - pr "{\n"; - pr " CAMLparam0 ();\n"; - pr " CAMLlocal2 (rv, v);\n"; - pr "\n"; - pr " rv = caml_alloc (%d, 0);\n" (List.length dirent_cols); - iteri ( - fun i col -> - (match col with - | name, `String -> - pr " v = caml_copy_string (dirent->%s);\n" name - | name, `Int -> - pr " v = caml_copy_int64 (dirent->%s);\n" name - | name, `Char -> - pr " v = Val_int (dirent->%s);\n" name - ); - pr " Store_field (rv, %d, v);\n" i - ) dirent_cols; - pr " CAMLreturn (rv);\n"; - pr "}\n"; - pr "\n"; - - pr "static CAMLprim value\n"; - pr "copy_dirent_list (const struct guestfs_dirent_list *dirents)\n"; - pr "{\n"; - pr " CAMLparam0 ();\n"; - pr " CAMLlocal2 (rv, v);\n"; - pr " int i;\n"; - pr "\n"; - pr " if (dirents->len == 0)\n"; - pr " CAMLreturn (Atom (0));\n"; - pr " else {\n"; - pr " rv = caml_alloc (dirents->len, 0);\n"; - pr " for (i = 0; i < dirents->len; ++i) {\n"; - pr " v = copy_dirent (&dirents->val[i]);\n"; - pr " caml_modify (&Field (rv, i), v);\n"; - pr " }\n"; - pr " CAMLreturn (rv);\n"; - pr " }\n"; - pr "}\n"; - pr "\n"; + ) structs; (* The wrappers. *) List.iter ( @@ -5868,24 +5639,14 @@ copy_table (char * const * argv) pr " int i;\n"; pr " char **r;\n"; "NULL" - | RIntBool _ -> - pr " struct guestfs_int_bool *r;\n"; "NULL" - | RPVList _ -> - pr " struct guestfs_lvm_pv_list *r;\n"; "NULL" - | RVGList _ -> - pr " struct guestfs_lvm_vg_list *r;\n"; "NULL" - | RLVList _ -> - pr " struct guestfs_lvm_lv_list *r;\n"; "NULL" - | RStat _ -> - pr " struct guestfs_stat *r;\n"; "NULL" - | RStatVFS _ -> - pr " struct guestfs_statvfs *r;\n"; "NULL" + | RStruct (_, typ) -> + pr " struct guestfs_%s *r;\n" typ; "NULL" + | RStructList (_, typ) -> + pr " struct guestfs_%s_list *r;\n" typ; "NULL" | RHashtable _ -> pr " int i;\n"; pr " char **r;\n"; - "NULL" - | RDirentList _ -> - pr " struct guestfs_dirent_list *r;\n"; "NULL" in + "NULL" in pr "\n"; pr " caml_enter_blocking_section ();\n"; @@ -5919,33 +5680,16 @@ copy_table (char * const * argv) pr " rv = caml_copy_string_array ((const char **) r);\n"; pr " for (i = 0; r[i] != NULL; ++i) free (r[i]);\n"; pr " free (r);\n" - | RIntBool _ -> - pr " rv = caml_alloc (2, 0);\n"; - pr " Store_field (rv, 0, Val_int (r->i));\n"; - pr " Store_field (rv, 1, Val_bool (r->b));\n"; - pr " guestfs_free_int_bool (r);\n"; - | RPVList _ -> - pr " rv = copy_lvm_pv_list (r);\n"; - pr " guestfs_free_lvm_pv_list (r);\n"; - | RVGList _ -> - pr " rv = copy_lvm_vg_list (r);\n"; - pr " guestfs_free_lvm_vg_list (r);\n"; - | RLVList _ -> - pr " rv = copy_lvm_lv_list (r);\n"; - pr " guestfs_free_lvm_lv_list (r);\n"; - | RStat _ -> - pr " rv = copy_stat (r);\n"; - pr " free (r);\n"; - | RStatVFS _ -> - pr " rv = copy_statvfs (r);\n"; - pr " free (r);\n"; + | RStruct (_, typ) -> + pr " rv = copy_%s (r);\n" typ; + pr " guestfs_free_%s (r);\n" typ; + | RStructList (_, typ) -> + pr " rv = copy_%s_list (r);\n" typ; + pr " guestfs_free_%s_list (r);\n" typ; | RHashtable _ -> pr " rv = copy_table (r);\n"; pr " for (i = 0; r[i] != NULL; ++i) free (r[i]);\n"; pr " free (r);\n"; - | RDirentList _ -> - pr " rv = copy_dirent_list (r);\n"; - pr " guestfs_free_dirent_list (r);\n"; ); pr " CAMLreturn (rv);\n"; @@ -5964,44 +5708,22 @@ copy_table (char * const * argv) ) ) all_functions -and generate_ocaml_lvm_structure_decls () = - List.iter ( - fun (typ, cols) -> - pr "type lvm_%s = {\n" typ; - List.iter ( - function - | name, `String -> pr " %s : string;\n" name - | name, `UUID -> pr " %s : string;\n" name - | name, `Bytes -> pr " %s : int64;\n" name - | name, `Int -> pr " %s : int64;\n" name - | name, `OptPercent -> pr " %s : float option;\n" name - ) cols; - pr "}\n"; - pr "\n" - ) ["pv", pv_cols; "vg", vg_cols; "lv", lv_cols] - -and generate_ocaml_stat_structure_decls () = +and generate_ocaml_structure_decls () = List.iter ( fun (typ, cols) -> pr "type %s = {\n" typ; List.iter ( function - | name, `Int -> pr " %s : int64;\n" name + | name, FString -> pr " %s : string;\n" name + | name, FUUID -> pr " %s : string;\n" name + | name, (FBytes|FInt64|FUInt64) -> pr " %s : int64;\n" name + | name, (FInt32|FUInt32) -> pr " %s : int32;\n" name + | name, FChar -> pr " %s : char;\n" name + | name, FOptPercent -> pr " %s : float option;\n" name ) cols; pr "}\n"; pr "\n" - ) ["stat", stat_cols; "statvfs", statvfs_cols] - -and generate_ocaml_dirent_structure_decls () = - pr "type dirent = {\n"; - List.iter ( - function - | name, `Int -> pr " %s : int64;\n" name - | name, `Char -> pr " %s : char;\n" name - | name, `String -> pr " %s : string;\n" name - ) dirent_cols; - pr "}\n"; - pr "\n" + ) structs and generate_ocaml_prototype ?(is_external = false) name style = if is_external then pr "external " else pr "val "; @@ -6022,14 +5744,9 @@ and generate_ocaml_prototype ?(is_external = false) name style = | RConstString _ -> pr "string" | RString _ -> pr "string" | RStringList _ -> pr "string array" - | RIntBool _ -> pr "int * bool" - | RPVList _ -> pr "lvm_pv array" - | RVGList _ -> pr "lvm_vg array" - | RLVList _ -> pr "lvm_lv array" - | RStat _ -> pr "stat" - | RStatVFS _ -> pr "statvfs" + | RStruct (_, typ) -> pr "%s" typ + | RStructList (_, typ) -> pr "%s array" typ | RHashtable _ -> pr "(string * string) list" - | RDirentList _ -> pr "dirent array" ); if is_external then ( pr " = "; @@ -6143,11 +5860,8 @@ DESTROY (g) | RConstString _ -> pr "SV *\n" | RString _ -> pr "SV *\n" | RStringList _ - | RIntBool _ - | RPVList _ | RVGList _ | RLVList _ - | RStat _ | RStatVFS _ - | RHashtable _ - | RDirentList _ -> + | RStruct _ | RStructList _ + | RHashtable _ -> pr "void\n" (* all lists returned implictly on the stack *) ); (* Call and arguments. *) @@ -6263,42 +5977,20 @@ DESTROY (g) pr " free (%s[i]);\n" n; pr " }\n"; pr " free (%s);\n" n; - | RIntBool _ -> - pr "PREINIT:\n"; - pr " struct guestfs_int_bool *r;\n"; - pr " PPCODE:\n"; - pr " r = guestfs_%s " name; - generate_call_args ~handle:"g" (snd style); - pr ";\n"; - do_cleanups (); - pr " if (r == NULL)\n"; - pr " croak (\"%s: %%s\", guestfs_last_error (g));\n" name; - pr " EXTEND (SP, 2);\n"; - pr " PUSHs (sv_2mortal (newSViv (r->i)));\n"; - pr " PUSHs (sv_2mortal (newSViv (r->b)));\n"; - pr " guestfs_free_int_bool (r);\n"; - | RPVList n -> - generate_perl_lvm_code "pv" pv_cols name style n do_cleanups - | RVGList n -> - generate_perl_lvm_code "vg" vg_cols name style n do_cleanups - | RLVList n -> - generate_perl_lvm_code "lv" lv_cols name style n do_cleanups - | RStat n -> - generate_perl_stat_code "stat" stat_cols name style n do_cleanups - | RStatVFS n -> - generate_perl_stat_code - "statvfs" statvfs_cols name style n do_cleanups - | RDirentList n -> - generate_perl_dirent_code - "dirent" dirent_cols name style n do_cleanups + | RStruct (n, typ) -> + let cols = cols_of_struct typ in + generate_perl_struct_code typ cols name style n do_cleanups + | RStructList (n, typ) -> + let cols = cols_of_struct typ in + generate_perl_struct_list_code typ cols name style n do_cleanups ); pr "\n" ) all_functions -and generate_perl_lvm_code typ cols name style n do_cleanups = +and generate_perl_struct_list_code typ cols name style n do_cleanups = pr "PREINIT:\n"; - pr " struct guestfs_lvm_%s_list *%s;\n" typ n; + pr " struct guestfs_%s_list *%s;\n" typ n; pr " int i;\n"; pr " HV *hv;\n"; pr " PPCODE:\n"; @@ -6313,27 +6005,33 @@ and generate_perl_lvm_code typ cols name style n do_cleanups = pr " hv = newHV ();\n"; List.iter ( function - | name, `String -> + | name, FString -> pr " (void) hv_store (hv, \"%s\", %d, newSVpv (%s->val[i].%s, 0), 0);\n" name (String.length name) n name - | name, `UUID -> + | name, FUUID -> pr " (void) hv_store (hv, \"%s\", %d, newSVpv (%s->val[i].%s, 32), 0);\n" name (String.length name) n name - | name, `Bytes -> + | name, (FBytes|FUInt64) -> pr " (void) hv_store (hv, \"%s\", %d, my_newSVull (%s->val[i].%s), 0);\n" name (String.length name) n name - | name, `Int -> + | name, FInt64 -> pr " (void) hv_store (hv, \"%s\", %d, my_newSVll (%s->val[i].%s), 0);\n" name (String.length name) n name - | name, `OptPercent -> + | name, (FInt32|FUInt32) -> + pr " (void) hv_store (hv, \"%s\", %d, newSVnv (%s->val[i].%s), 0);\n" + name (String.length name) n name + | name, FChar -> + pr " (void) hv_store (hv, \"%s\", %d, newSVpv (&%s->val[i].%s, 1), 0);\n" + name (String.length name) n name + | name, FOptPercent -> pr " (void) hv_store (hv, \"%s\", %d, newSVnv (%s->val[i].%s), 0);\n" name (String.length name) n name ) cols; pr " PUSHs (sv_2mortal (newRV ((SV *) hv)));\n"; pr " }\n"; - pr " guestfs_free_lvm_%s_list (%s);\n" typ n + pr " guestfs_free_%s_list (%s);\n" typ n -and generate_perl_stat_code typ cols name style n do_cleanups = +and generate_perl_struct_code typ cols name style n do_cleanups = pr "PREINIT:\n"; pr " struct guestfs_%s *%s;\n" typ n; pr " PPCODE:\n"; @@ -6346,42 +6044,30 @@ and generate_perl_stat_code typ cols name style n do_cleanups = pr " EXTEND (SP, %d);\n" (List.length cols); List.iter ( function - | name, `Int -> - pr " PUSHs (sv_2mortal (my_newSVll (%s->%s)));\n" n name + | name, FString -> + pr " PUSHs (sv_2mortal (newSVpv (%s->%s, 0)));\n" + n name + | name, FUUID -> + pr " PUSHs (sv_2mortal (newSVpv (%s->%s, 32)));\n" + n name + | name, (FBytes|FUInt64) -> + pr " PUSHs (sv_2mortal (my_newSVull (%s->%s)));\n" + n name + | name, FInt64 -> + pr " PUSHs (sv_2mortal (my_newSVll (%s->%s)));\n" + n name + | name, (FInt32|FUInt32) -> + pr " PUSHs (sv_2mortal (newSVnv (%s->%s)));\n" + n name + | name, FChar -> + pr " PUSHs (sv_2mortal (newSVpv (&%s->%s, 1)));\n" + n name + | name, FOptPercent -> + pr " PUSHs (sv_2mortal (newSVnv (%s->%s)));\n" + n name ) cols; pr " free (%s);\n" n -and generate_perl_dirent_code typ cols name style n do_cleanups = - pr "PREINIT:\n"; - pr " struct guestfs_%s_list *%s;\n" typ n; - pr " int i;\n"; - pr " HV *hv;\n"; - pr " PPCODE:\n"; - pr " %s = guestfs_%s " n name; - generate_call_args ~handle:"g" (snd style); - pr ";\n"; - do_cleanups (); - pr " if (%s == NULL)\n" n; - pr " croak (\"%s: %%s\", guestfs_last_error (g));\n" name; - pr " EXTEND (SP, %s->len);\n" n; - pr " for (i = 0; i < %s->len; ++i) {\n" n; - pr " hv = newHV ();\n"; - List.iter ( - function - | name, `String -> - pr " (void) hv_store (hv, \"%s\", %d, newSVpv (%s->val[i].%s, 0), 0);\n" - name (String.length name) n name - | name, `Int -> - pr " (void) hv_store (hv, \"%s\", %d, my_newSVull (%s->val[i].%s), 0);\n" - name (String.length name) n name - | name, `Char -> - pr " (void) hv_store (hv, \"%s\", %d, newSVpv (&%s->val[i].%s, 1), 0);\n" - name (String.length name) n name - ) cols; - pr " PUSHs (newRV (sv_2mortal ((SV *) hv)));\n"; - pr " }\n"; - pr " guestfs_free_%s_list (%s);\n" typ n - (* Generate Sys/Guestfs.pm. *) and generate_perl_pm () = generate_header HashStyle LGPLv2; @@ -6396,7 +6082,7 @@ Sys::Guestfs - Perl bindings for libguestfs =head1 SYNOPSIS use Sys::Guestfs; - + my $h = Sys::Guestfs->new (); $h->add_drive ('guest.img'); $h->launch (); @@ -6511,15 +6197,10 @@ and generate_perl_prototype name style = | RInt64 n | RConstString n | RString n -> pr "$%s = " n - | RIntBool (n, m) -> pr "($%s, $%s) = " n m - | RStringList n - | RPVList n - | RVGList n - | RLVList n - | RDirentList n -> pr "@%s = " n - | RStat n - | RStatVFS n + | RStruct (n,_) | RHashtable n -> pr "%%%s = " n + | RStringList n + | RStructList (n,_) -> pr "@%s = " n ); pr "$h->%s (" name; let comma = ref false in @@ -6676,34 +6357,42 @@ py_guestfs_close (PyObject *self, PyObject *args) "; - (* LVM structures, turned into Python dictionaries. *) + (* Structures, turned into Python dictionaries. *) List.iter ( fun (typ, cols) -> pr "static PyObject *\n"; - pr "put_lvm_%s (struct guestfs_lvm_%s *%s)\n" typ typ typ; + pr "put_%s (struct guestfs_%s *%s)\n" typ typ typ; pr "{\n"; pr " PyObject *dict;\n"; pr "\n"; pr " dict = PyDict_New ();\n"; List.iter ( function - | name, `String -> + | name, FString -> pr " PyDict_SetItemString (dict, \"%s\",\n" name; pr " PyString_FromString (%s->%s));\n" typ name - | name, `UUID -> + | name, FUUID -> pr " PyDict_SetItemString (dict, \"%s\",\n" name; pr " PyString_FromStringAndSize (%s->%s, 32));\n" typ name - | name, `Bytes -> + | name, (FBytes|FUInt64) -> pr " PyDict_SetItemString (dict, \"%s\",\n" name; pr " PyLong_FromUnsignedLongLong (%s->%s));\n" typ name - | name, `Int -> + | name, FInt64 -> pr " PyDict_SetItemString (dict, \"%s\",\n" name; pr " PyLong_FromLongLong (%s->%s));\n" typ name - | name, `OptPercent -> + | name, FUInt32 -> + pr " PyDict_SetItemString (dict, \"%s\",\n" name; + pr " PyLong_FromUnsignedLong (%s->%s));\n" + typ name + | name, FInt32 -> + pr " PyDict_SetItemString (dict, \"%s\",\n" name; + pr " PyLong_FromLong (%s->%s));\n" + typ name + | name, FOptPercent -> pr " if (%s->%s >= 0)\n" typ name; pr " PyDict_SetItemString (dict, \"%s\",\n" name; pr " PyFloat_FromDouble ((double) %s->%s));\n" @@ -6712,81 +6401,27 @@ py_guestfs_close (PyObject *self, PyObject *args) pr " Py_INCREF (Py_None);\n"; pr " PyDict_SetItemString (dict, \"%s\", Py_None);" name; pr " }\n" + | name, FChar -> + pr " PyDict_SetItemString (dict, \"%s\",\n" name; + pr " PyString_FromStringAndSize (&dirent->%s, 1));\n" name ) cols; pr " return dict;\n"; pr "};\n"; pr "\n"; pr "static PyObject *\n"; - pr "put_lvm_%s_list (struct guestfs_lvm_%s_list *%ss)\n" typ typ typ; + pr "put_%s_list (struct guestfs_%s_list *%ss)\n" typ typ typ; pr "{\n"; pr " PyObject *list;\n"; pr " int i;\n"; pr "\n"; pr " list = PyList_New (%ss->len);\n" typ; pr " for (i = 0; i < %ss->len; ++i)\n" typ; - pr " PyList_SetItem (list, i, put_lvm_%s (&%ss->val[i]));\n" typ typ; + pr " PyList_SetItem (list, i, put_%s (&%ss->val[i]));\n" typ typ; pr " return list;\n"; pr "};\n"; pr "\n" - ) ["pv", pv_cols; "vg", vg_cols; "lv", lv_cols]; - - (* Stat structures, turned into Python dictionaries. *) - List.iter ( - fun (typ, cols) -> - pr "static PyObject *\n"; - pr "put_%s (struct guestfs_%s *%s)\n" typ typ typ; - pr "{\n"; - pr " PyObject *dict;\n"; - pr "\n"; - pr " dict = PyDict_New ();\n"; - List.iter ( - function - | name, `Int -> - pr " PyDict_SetItemString (dict, \"%s\",\n" name; - pr " PyLong_FromLongLong (%s->%s));\n" - typ name - ) cols; - pr " return dict;\n"; - pr "};\n"; - pr "\n"; - ) ["stat", stat_cols; "statvfs", statvfs_cols]; - - (* Dirent structures, turned into Python dictionaries. *) - pr "static PyObject *\n"; - pr "put_dirent (struct guestfs_dirent *dirent)\n"; - pr "{\n"; - pr " PyObject *dict;\n"; - pr "\n"; - pr " dict = PyDict_New ();\n"; - List.iter ( - function - | name, `Int -> - pr " PyDict_SetItemString (dict, \"%s\",\n" name; - pr " PyLong_FromLongLong (dirent->%s));\n" name - | name, `Char -> - pr " PyDict_SetItemString (dict, \"%s\",\n" name; - pr " PyString_FromStringAndSize (&dirent->%s, 1));\n" name - | name, `String -> - pr " PyDict_SetItemString (dict, \"%s\",\n" name; - pr " PyString_FromString (dirent->%s));\n" name - ) dirent_cols; - pr " return dict;\n"; - pr "};\n"; - pr "\n"; - - pr "static PyObject *\n"; - pr "put_dirent_list (struct guestfs_dirent_list *dirents)\n"; - pr "{\n"; - pr " PyObject *list;\n"; - pr " int i;\n"; - pr "\n"; - pr " list = PyList_New (dirents->len);\n"; - pr " for (i = 0; i < dirents->len; ++i)\n"; - pr " PyList_SetItem (list, i, put_dirent (&dirents->val[i]));\n"; - pr " return list;\n"; - pr "};\n"; - pr "\n"; + ) structs; (* Python wrapper functions. *) List.iter ( @@ -6806,13 +6441,9 @@ py_guestfs_close (PyObject *self, PyObject *args) | RConstString _ -> pr " const char *r;\n"; "NULL" | RString _ -> pr " char *r;\n"; "NULL" | RStringList _ | RHashtable _ -> pr " char **r;\n"; "NULL" - | RIntBool _ -> pr " struct guestfs_int_bool *r;\n"; "NULL" - | RPVList n -> pr " struct guestfs_lvm_pv_list *r;\n"; "NULL" - | RVGList n -> pr " struct guestfs_lvm_vg_list *r;\n"; "NULL" - | RLVList n -> pr " struct guestfs_lvm_lv_list *r;\n"; "NULL" - | RStat n -> pr " struct guestfs_stat *r;\n"; "NULL" - | RStatVFS n -> pr " struct guestfs_statvfs *r;\n"; "NULL" - | RDirentList n -> pr " struct guestfs_dirent_list *r;\n"; "NULL" in + | RStruct (_, typ) -> pr " struct guestfs_%s *r;\n" typ; "NULL" + | RStructList (_, typ) -> + pr " struct guestfs_%s_list *r;\n" typ; "NULL" in List.iter ( function @@ -6893,32 +6524,15 @@ py_guestfs_close (PyObject *self, PyObject *args) | RStringList _ -> pr " py_r = put_string_list (r);\n"; pr " free_strings (r);\n" - | RIntBool _ -> - pr " py_r = PyTuple_New (2);\n"; - pr " PyTuple_SetItem (py_r, 0, PyInt_FromLong ((long) r->i));\n"; - pr " PyTuple_SetItem (py_r, 1, PyInt_FromLong ((long) r->b));\n"; - pr " guestfs_free_int_bool (r);\n" - | RPVList n -> - pr " py_r = put_lvm_pv_list (r);\n"; - pr " guestfs_free_lvm_pv_list (r);\n" - | RVGList n -> - pr " py_r = put_lvm_vg_list (r);\n"; - pr " guestfs_free_lvm_vg_list (r);\n" - | RLVList n -> - pr " py_r = put_lvm_lv_list (r);\n"; - pr " guestfs_free_lvm_lv_list (r);\n" - | RStat n -> - pr " py_r = put_stat (r);\n"; - pr " free (r);\n" - | RStatVFS n -> - pr " py_r = put_statvfs (r);\n"; - pr " free (r);\n" + | RStruct (_, typ) -> + pr " py_r = put_%s (r);\n" typ; + pr " guestfs_free_%s (r);\n" typ + | RStructList (_, typ) -> + pr " py_r = put_%s_list (r);\n" typ; + pr " guestfs_free_%s_list (r);\n" typ | RHashtable n -> pr " py_r = put_table (r);\n"; pr " free_strings (r);\n" - | RDirentList n -> - pr " py_r = put_dirent_list (r);\n"; - pr " guestfs_free_dirent_list (r);\n" ); pr " return py_r;\n"; @@ -7033,22 +6647,12 @@ class GuestFS: | RString _ -> doc | RStringList _ -> doc ^ "\n\nThis function returns a list of strings." - | RIntBool _ -> - doc ^ "\n\nThis function returns a tuple (int, bool).\n" - | RPVList _ -> - doc ^ "\n\nThis function returns a list of PVs. Each PV is represented as a dictionary." - | RVGList _ -> - doc ^ "\n\nThis function returns a list of VGs. Each VG is represented as a dictionary." - | RLVList _ -> - doc ^ "\n\nThis function returns a list of LVs. Each LV is represented as a dictionary." - | RStat _ -> - doc ^ "\n\nThis function returns a dictionary, with keys matching the various fields in the stat structure." - | RStatVFS _ -> - doc ^ "\n\nThis function returns a dictionary, with keys matching the various fields in the statvfs structure." + | RStruct (_, typ) -> + doc ^ sprintf "\n\nThis function returns a dictionary, with keys matching the various fields in the guestfs_%s structure." typ + | RStructList (_, typ) -> + doc ^ sprintf "\n\nThis function returns a list of %ss. Each %s is represented as a dictionary." typ typ | RHashtable _ -> - doc ^ "\n\nThis function returns a dictionary." - | RDirentList _ -> - doc ^ "\n\nThis function returns a list of directory entries. Each directory entry is represented as a dictionary." in + doc ^ "\n\nThis function returns a dictionary." in let doc = if List.mem ProtocolLimitWarning flags then doc ^ "\n\n" ^ protocol_limit_warning @@ -7218,13 +6822,9 @@ static VALUE ruby_guestfs_close (VALUE gv) | RConstString _ -> pr " const char *r;\n"; "NULL" | RString _ -> pr " char *r;\n"; "NULL" | RStringList _ | RHashtable _ -> pr " char **r;\n"; "NULL" - | RIntBool _ -> pr " struct guestfs_int_bool *r;\n"; "NULL" - | RPVList n -> pr " struct guestfs_lvm_pv_list *r;\n"; "NULL" - | RVGList n -> pr " struct guestfs_lvm_vg_list *r;\n"; "NULL" - | RLVList n -> pr " struct guestfs_lvm_lv_list *r;\n"; "NULL" - | RStat n -> pr " struct guestfs_stat *r;\n"; "NULL" - | RStatVFS n -> pr " struct guestfs_statvfs *r;\n"; "NULL" - | RDirentList n -> pr " struct guestfs_dirent_list *r;\n"; "NULL" in + | RStruct (_, typ) -> pr " struct guestfs_%s *r;\n" typ; "NULL" + | RStructList (_, typ) -> + pr " struct guestfs_%s_list *r;\n" typ; "NULL" in pr "\n"; pr " r = guestfs_%s " name; @@ -7265,36 +6865,12 @@ static VALUE ruby_guestfs_close (VALUE gv) pr " }\n"; pr " free (r);\n"; pr " return rv;\n" - | RIntBool _ -> - pr " VALUE rv = rb_ary_new2 (2);\n"; - pr " rb_ary_push (rv, INT2NUM (r->i));\n"; - pr " rb_ary_push (rv, INT2NUM (r->b));\n"; - pr " guestfs_free_int_bool (r);\n"; - pr " return rv;\n" - | RPVList n -> - generate_ruby_lvm_code "pv" pv_cols - | RVGList n -> - generate_ruby_lvm_code "vg" vg_cols - | RLVList n -> - generate_ruby_lvm_code "lv" lv_cols - | RStat n -> - pr " VALUE rv = rb_hash_new ();\n"; - List.iter ( - function - | name, `Int -> - pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), ULL2NUM (r->%s));\n" name name - ) stat_cols; - pr " free (r);\n"; - pr " return rv;\n" - | RStatVFS n -> - pr " VALUE rv = rb_hash_new ();\n"; - List.iter ( - function - | name, `Int -> - pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), ULL2NUM (r->%s));\n" name name - ) statvfs_cols; - pr " free (r);\n"; - pr " return rv;\n" + | RStruct (_, typ) -> + let cols = cols_of_struct typ in + generate_ruby_struct_code typ cols + | RStructList (_, typ) -> + let cols = cols_of_struct typ in + generate_ruby_struct_list_code typ cols | RHashtable _ -> pr " VALUE rv = rb_hash_new ();\n"; pr " int i;\n"; @@ -7305,8 +6881,6 @@ static VALUE ruby_guestfs_close (VALUE gv) pr " }\n"; pr " free (r);\n"; pr " return rv;\n" - | RDirentList n -> - generate_ruby_dirent_code "dirent" dirent_cols ); pr "}\n"; @@ -7334,41 +6908,55 @@ void Init__guestfs () pr "}\n" -(* Ruby code to return an LVM struct list. *) -and generate_ruby_lvm_code typ cols = - pr " VALUE rv = rb_ary_new2 (r->len);\n"; - pr " int i;\n"; - pr " for (i = 0; i < r->len; ++i) {\n"; - pr " VALUE hv = rb_hash_new ();\n"; +(* Ruby code to return a struct. *) +and generate_ruby_struct_code typ cols = + pr " VALUE rv = rb_hash_new ();\n"; List.iter ( function - | name, `String -> - pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), rb_str_new2 (r->val[i].%s));\n" name name - | name, `UUID -> - pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), rb_str_new (r->val[i].%s, 32));\n" name name - | name, `Bytes - | name, `Int -> - pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), ULL2NUM (r->val[i].%s));\n" name name - | name, `OptPercent -> - pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), rb_dbl2big (r->val[i].%s));\n" name name + | name, FString -> + pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), rb_str_new2 (r->%s));\n" name name + | name, FUUID -> + pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), rb_str_new (r->%s, 32));\n" name name + | name, (FBytes|FUInt64) -> + pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), ULL2NUM (r->%s));\n" name name + | name, FInt64 -> + pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), LL2NUM (r->%s));\n" name name + | name, FUInt32 -> + pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), UINT2NUM (r->%s));\n" name name + | name, FInt32 -> + pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), INT2NUM (r->%s));\n" name name + | name, FOptPercent -> + pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), rb_dbl2big (r->%s));\n" name name + | name, FChar -> (* XXX wrong? *) + pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), ULL2NUM (r->%s));\n" name name ) cols; - pr " rb_ary_push (rv, hv);\n"; - pr " }\n"; - pr " guestfs_free_lvm_%s_list (r);\n" typ; + pr " guestfs_free_%s (r);\n" typ; pr " return rv;\n" -(* Ruby code to return a dirent struct list. *) -and generate_ruby_dirent_code typ cols = +(* Ruby code to return a struct list. *) +and generate_ruby_struct_list_code typ cols = pr " VALUE rv = rb_ary_new2 (r->len);\n"; pr " int i;\n"; pr " for (i = 0; i < r->len; ++i) {\n"; pr " VALUE hv = rb_hash_new ();\n"; List.iter ( function - | name, `String -> - pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), rb_str_new2 (r->val[i].%s));\n" name name - | name, (`Char|`Int) -> - pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), ULL2NUM (r->val[i].%s));\n" name name + | name, FString -> + pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), rb_str_new2 (r->val[i].%s));\n" name name + | name, FUUID -> + pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), rb_str_new (r->val[i].%s, 32));\n" name name + | name, (FBytes|FUInt64) -> + pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), ULL2NUM (r->val[i].%s));\n" name name + | name, FInt64 -> + pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), LL2NUM (r->val[i].%s));\n" name name + | name, FUInt32 -> + pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), UINT2NUM (r->val[i].%s));\n" name name + | name, FInt32 -> + pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), INT2NUM (r->val[i].%s));\n" name name + | name, FOptPercent -> + pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), rb_dbl2big (r->val[i].%s));\n" name name + | name, FChar -> (* XXX wrong? *) + pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), ULL2NUM (r->val[i].%s));\n" name name ) cols; pr " rb_ary_push (rv, hv);\n"; pr " }\n"; @@ -7507,14 +7095,13 @@ and generate_java_prototype ?(public=false) ?(privat=false) ?(native=false) | RBool _ -> pr "boolean "; | RConstString _ | RString _ -> pr "String "; | RStringList _ -> pr "String[] "; - | RIntBool _ -> pr "IntBool "; - | RPVList _ -> pr "PV[] "; - | RVGList _ -> pr "VG[] "; - | RLVList _ -> pr "LV[] "; - | RStat _ -> pr "Stat "; - | RStatVFS _ -> pr "StatVFS "; + | RStruct (_, typ) -> + let name = java_name_of_struct typ in + pr "%s " name; + | RStructList (_, typ) -> + let name = java_name_of_struct typ in + pr "%s[] " name; | RHashtable _ -> pr "HashMap "; - | RDirentList _ -> pr "Dirent[] "; ); if native then pr "_%s " name else pr "%s " name; @@ -7549,7 +7136,7 @@ and generate_java_prototype ?(public=false) ?(privat=false) ?(native=false) pr " throws LibGuestFSException"; if semicolon then pr ";" -and generate_java_struct typ cols = +and generate_java_struct jtyp cols = generate_header CStyle LGPLv2; pr "\ @@ -7562,16 +7149,16 @@ package com.redhat.et.libguestfs; * @see GuestFS */ public class %s { -" typ typ; +" jtyp jtyp; List.iter ( function - | name, `String - | name, `UUID -> pr " public String %s;\n" name - | name, `Bytes - | name, `Int -> pr " public long %s;\n" name - | name, `Char -> pr " public char %s;\n" name - | name, `OptPercent -> + | name, FString + | name, FUUID -> pr " public String %s;\n" name + | name, (FBytes|FUInt64|FInt64) -> pr " public long %s;\n" name + | name, (FUInt32|FInt32) -> pr " public int %s;\n" name + | name, FChar -> pr " public char %s;\n" name + | name, FOptPercent -> pr " /* The next field is [0..100] or -1 meaning 'not present': */\n"; pr " public float %s;\n" name ) cols; @@ -7635,9 +7222,9 @@ Java_com_redhat_et_libguestfs_GuestFS__1close | RInt64 _ -> pr "jlong "; | RBool _ -> pr "jboolean "; | RConstString _ | RString _ -> pr "jstring "; - | RIntBool _ | RStat _ | RStatVFS _ | RHashtable _ -> + | RStruct _ | RHashtable _ -> pr "jobject "; - | RStringList _ | RPVList _ | RVGList _ | RLVList _ | RDirentList _ -> + | RStringList _ | RStructList _ -> pr "jobjectArray "; ); pr "JNICALL\n"; @@ -7678,46 +7265,18 @@ Java_com_redhat_et_libguestfs_GuestFS__1close pr " jclass cl;\n"; pr " jstring jstr;\n"; pr " char **r;\n"; "NULL", "NULL" - | RIntBool _ -> + | RStruct (_, typ) -> pr " jobject jr;\n"; pr " jclass cl;\n"; pr " jfieldID fl;\n"; - pr " struct guestfs_int_bool *r;\n"; "NULL", "NULL" - | RStat _ -> - pr " jobject jr;\n"; - pr " jclass cl;\n"; - pr " jfieldID fl;\n"; - pr " struct guestfs_stat *r;\n"; "NULL", "NULL" - | RStatVFS _ -> - pr " jobject jr;\n"; - pr " jclass cl;\n"; - pr " jfieldID fl;\n"; - pr " struct guestfs_statvfs *r;\n"; "NULL", "NULL" - | RPVList _ -> - pr " jobjectArray jr;\n"; - pr " jclass cl;\n"; - pr " jfieldID fl;\n"; - pr " jobject jfl;\n"; - pr " struct guestfs_lvm_pv_list *r;\n"; "NULL", "NULL" - | RVGList _ -> - pr " jobjectArray jr;\n"; - pr " jclass cl;\n"; - pr " jfieldID fl;\n"; - pr " jobject jfl;\n"; - pr " struct guestfs_lvm_vg_list *r;\n"; "NULL", "NULL" - | RLVList _ -> + pr " struct guestfs_%s *r;\n" typ; "NULL", "NULL" + | RStructList (_, typ) -> pr " jobjectArray jr;\n"; pr " jclass cl;\n"; pr " jfieldID fl;\n"; pr " jobject jfl;\n"; - pr " struct guestfs_lvm_lv_list *r;\n"; "NULL", "NULL" - | RHashtable _ -> pr " char **r;\n"; "NULL", "NULL" - | RDirentList _ -> - pr " jobjectArray jr;\n"; - pr " jclass cl;\n"; - pr " jfieldID fl;\n"; - pr " jobject jfl;\n"; - pr " struct guestfs_dirent_list *r;\n"; "NULL", "NULL" in + pr " struct guestfs_%s_list *r;\n" typ; "NULL", "NULL" + | RHashtable _ -> pr " char **r;\n"; "NULL", "NULL" in List.iter ( function | String n @@ -7735,11 +7294,9 @@ Java_com_redhat_et_libguestfs_GuestFS__1close let needs_i = (match fst style with - | RStringList _ | RPVList _ | RVGList _ | RLVList _ - | RDirentList _ -> true + | RStringList _ | RStructList _ -> true | RErr | RBool _ | RInt _ | RInt64 _ | RConstString _ - | RString _ | RIntBool _ | RStat _ | RStatVFS _ - | RHashtable _ -> false) || + | RString _ | RStruct _ | RHashtable _ -> false) || List.exists (function StringList _ -> true | _ -> false) (snd style) in if needs_i then pr " int i;\n"; @@ -7827,68 +7384,67 @@ Java_com_redhat_et_libguestfs_GuestFS__1close pr " }\n"; pr " free (r);\n"; pr " return jr;\n" - | RIntBool _ -> - pr " cl = (*env)->FindClass (env, \"com/redhat/et/libguestfs/IntBool\");\n"; - pr " jr = (*env)->AllocObject (env, cl);\n"; - pr " fl = (*env)->GetFieldID (env, cl, \"i\", \"I\");\n"; - pr " (*env)->SetIntField (env, jr, fl, r->i);\n"; - pr " fl = (*env)->GetFieldID (env, cl, \"i\", \"Z\");\n"; - pr " (*env)->SetBooleanField (env, jr, fl, r->b);\n"; - pr " guestfs_free_int_bool (r);\n"; - pr " return jr;\n" - | RStat _ -> - pr " cl = (*env)->FindClass (env, \"com/redhat/et/libguestfs/Stat\");\n"; - pr " jr = (*env)->AllocObject (env, cl);\n"; - List.iter ( - function - | name, `Int -> - pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"J\");\n" - name; - pr " (*env)->SetLongField (env, jr, fl, r->%s);\n" name; - ) stat_cols; - pr " free (r);\n"; - pr " return jr;\n" - | RStatVFS _ -> - pr " cl = (*env)->FindClass (env, \"com/redhat/et/libguestfs/StatVFS\");\n"; - pr " jr = (*env)->AllocObject (env, cl);\n"; - List.iter ( - function - | name, `Int -> - pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"J\");\n" - name; - pr " (*env)->SetLongField (env, jr, fl, r->%s);\n" name; - ) statvfs_cols; - pr " free (r);\n"; - pr " return jr;\n" - | RPVList _ -> - generate_java_lvm_return "pv" "PV" pv_cols - | RVGList _ -> - generate_java_lvm_return "vg" "VG" vg_cols - | RLVList _ -> - generate_java_lvm_return "lv" "LV" lv_cols + | RStruct (_, typ) -> + let jtyp = java_name_of_struct typ in + let cols = cols_of_struct typ in + generate_java_struct_return typ jtyp cols + | RStructList (_, typ) -> + let jtyp = java_name_of_struct typ in + let cols = cols_of_struct typ in + generate_java_struct_list_return typ jtyp cols | RHashtable _ -> (* XXX *) pr " throw_exception (env, \"%s: internal error: please let us know how to make a Java HashMap from JNI bindings!\");\n" name; pr " return NULL;\n" - | RDirentList _ -> - generate_java_dirent_return "dirent" "Dirent" dirent_cols ); pr "}\n"; pr "\n" ) all_functions -and generate_java_lvm_return typ jtyp cols = +and generate_java_struct_return typ jtyp cols = + pr " cl = (*env)->FindClass (env, \"com/redhat/et/libguestfs/%s\");\n" jtyp; + pr " jr = (*env)->AllocObject (env, cl);\n"; + List.iter ( + function + | name, FString -> + pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"Ljava/lang/String;\");\n" name; + pr " (*env)->SetObjectField (env, jr, fl, (*env)->NewStringUTF (env, r->%s));\n" name; + | name, FUUID -> + pr " {\n"; + pr " char s[33];\n"; + pr " memcpy (s, r->%s, 32);\n" name; + pr " s[32] = 0;\n"; + pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"Ljava/lang/String;\");\n" name; + pr " (*env)->SetObjectField (env, jr, fl, (*env)->NewStringUTF (env, s));\n"; + pr " }\n"; + | name, (FBytes|FUInt64|FInt64) -> + pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"J\");\n" name; + pr " (*env)->SetLongField (env, jr, fl, r->%s);\n" name; + | name, (FUInt32|FInt32) -> + pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"I\");\n" name; + pr " (*env)->SetLongField (env, jr, fl, r->%s);\n" name; + | name, FOptPercent -> + pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"F\");\n" name; + pr " (*env)->SetFloatField (env, jr, fl, r->%s);\n" name; + | name, FChar -> + pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"C\");\n" name; + pr " (*env)->SetLongField (env, jr, fl, r->%s);\n" name; + ) cols; + pr " free (r);\n"; + pr " return jr;\n" + +and generate_java_struct_list_return typ jtyp cols = pr " cl = (*env)->FindClass (env, \"com/redhat/et/libguestfs/%s\");\n" jtyp; pr " jr = (*env)->NewObjectArray (env, r->len, cl, NULL);\n"; pr " for (i = 0; i < r->len; ++i) {\n"; pr " jfl = (*env)->AllocObject (env, cl);\n"; List.iter ( function - | name, `String -> + | name, FString -> pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"Ljava/lang/String;\");\n" name; pr " (*env)->SetObjectField (env, jfl, fl, (*env)->NewStringUTF (env, r->val[i].%s));\n" name; - | name, `UUID -> + | name, FUUID -> pr " {\n"; pr " char s[33];\n"; pr " memcpy (s, r->val[i].%s, 32);\n" name; @@ -7896,30 +7452,17 @@ and generate_java_lvm_return typ jtyp cols = pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"Ljava/lang/String;\");\n" name; pr " (*env)->SetObjectField (env, jfl, fl, (*env)->NewStringUTF (env, s));\n"; pr " }\n"; - | name, (`Bytes|`Int) -> + | name, (FBytes|FUInt64|FInt64) -> pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"J\");\n" name; pr " (*env)->SetLongField (env, jfl, fl, r->val[i].%s);\n" name; - | name, `OptPercent -> + | name, (FUInt32|FInt32) -> + pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"I\");\n" name; + pr " (*env)->SetLongField (env, jfl, fl, r->val[i].%s);\n" name; + | name, FOptPercent -> pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"F\");\n" name; pr " (*env)->SetFloatField (env, jfl, fl, r->val[i].%s);\n" name; - ) cols; - pr " (*env)->SetObjectArrayElement (env, jfl, i, jfl);\n"; - pr " }\n"; - pr " guestfs_free_lvm_%s_list (r);\n" typ; - pr " return jr;\n" - -and generate_java_dirent_return typ jtyp cols = - pr " cl = (*env)->FindClass (env, \"com/redhat/et/libguestfs/%s\");\n" jtyp; - pr " jr = (*env)->NewObjectArray (env, r->len, cl, NULL);\n"; - pr " for (i = 0; i < r->len; ++i) {\n"; - pr " jfl = (*env)->AllocObject (env, cl);\n"; - List.iter ( - function - | name, `String -> - pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"Ljava/lang/String;\");\n" name; - pr " (*env)->SetObjectField (env, jfl, fl, (*env)->NewStringUTF (env, r->val[i].%s));\n" name; - | name, (`Char|`Int) -> - pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"J\");\n" name; + | name, FChar -> + pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"C\");\n" name; pr " (*env)->SetLongField (env, jfl, fl, r->val[i].%s);\n" name; ) cols; pr " (*env)->SetObjectArrayElement (env, jfl, i, jfl);\n"; @@ -7942,14 +7485,9 @@ and generate_haskell_hs () = | RConstString _, _ | RString _, _ | RStringList _, _ - | RIntBool _, _ - | RPVList _, _ - | RVGList _, _ - | RLVList _, _ - | RStat _, _ - | RStatVFS _, _ - | RHashtable _, _ - | RDirentList _, _ -> false in + | RStruct _, _ + | RStructList _, _ + | RHashtable _, _ -> false in pr "\ {-# INCLUDE #-} @@ -8058,9 +7596,8 @@ last_error h = do pr " then do\n"; pr " err <- last_error h\n"; pr " fail err\n"; - | RConstString _ | RString _ | RStringList _ | RIntBool _ - | RPVList _ | RVGList _ | RLVList _ | RStat _ | RStatVFS _ - | RHashtable _ | RDirentList _ -> + | RConstString _ | RString _ | RStringList _ | RStruct _ + | RStructList _ | RHashtable _ -> pr " if (r == nullPtr)\n"; pr " then do\n"; pr " err <- last_error h\n"; @@ -8078,14 +7615,9 @@ last_error h = do | RConstString _ | RString _ | RStringList _ - | RIntBool _ - | RPVList _ - | RVGList _ - | RLVList _ - | RStat _ - | RStatVFS _ - | RHashtable _ - | RDirentList _ -> + | RStruct _ + | RStructList _ + | RHashtable _ -> pr " else return ()\n" (* XXXXXXXXXXXXXXXXXXXX *) ); pr "\n"; @@ -8120,14 +7652,13 @@ and generate_haskell_prototype ~handle ?(hs = false) style = | RConstString _ -> pr "%s" string | RString _ -> pr "%s" string | RStringList _ -> pr "[%s]" string - | RIntBool _ -> pr "IntBool" - | RPVList _ -> pr "[PV]" - | RVGList _ -> pr "[VG]" - | RLVList _ -> pr "[LV]" - | RStat _ -> pr "Stat" - | RStatVFS _ -> pr "StatVFS" + | RStruct (_, typ) -> + let name = java_name_of_struct typ in + pr "%s" name + | RStructList (_, typ) -> + let name = java_name_of_struct typ in + pr "[%s]" name | RHashtable _ -> pr "Hashtable" - | RDirentList _ -> pr "[Dirent]" ); pr ")" @@ -8144,6 +7675,8 @@ and generate_bindtests () = #include \"guestfs_protocol.h\" #define error guestfs_error +#define safe_calloc guestfs_safe_calloc +#define safe_malloc guestfs_safe_malloc static void print_strings (char * const* const argv) @@ -8219,84 +7752,36 @@ print_strings (char * const* const argv) pr " char **strs;\n"; pr " int n, i;\n"; pr " sscanf (val, \"%%d\", &n);\n"; - pr " strs = malloc ((n+1) * sizeof (char *));\n"; + pr " strs = safe_malloc (g, (n+1) * sizeof (char *));\n"; pr " for (i = 0; i < n; ++i) {\n"; - pr " strs[i] = malloc (16);\n"; + pr " strs[i] = safe_malloc (g, 16);\n"; pr " snprintf (strs[i], 16, \"%%d\", i);\n"; pr " }\n"; pr " strs[n] = NULL;\n"; pr " return strs;\n" - | RIntBool _ -> - pr " struct guestfs_int_bool *r;\n"; - pr " r = malloc (sizeof (struct guestfs_int_bool));\n"; - pr " sscanf (val, \"%%\" SCNi32, &r->i);\n"; - pr " r->b = 0;\n"; + | RStruct (_, typ) -> + pr " struct guestfs_%s *r;\n" typ; + pr " r = safe_calloc (g, sizeof *r, 1);\n"; pr " return r;\n" - | RPVList _ -> - pr " struct guestfs_lvm_pv_list *r;\n"; - pr " int i;\n"; - pr " r = malloc (sizeof (struct guestfs_lvm_pv_list));\n"; + | RStructList (_, typ) -> + pr " struct guestfs_%s_list *r;\n" typ; + pr " r = safe_calloc (g, sizeof *r, 1);\n"; pr " sscanf (val, \"%%d\", &r->len);\n"; - pr " r->val = calloc (r->len, sizeof (struct guestfs_lvm_pv));\n"; - pr " for (i = 0; i < r->len; ++i) {\n"; - pr " r->val[i].pv_name = malloc (16);\n"; - pr " snprintf (r->val[i].pv_name, 16, \"%%d\", i);\n"; - pr " }\n"; - pr " return r;\n" - | RVGList _ -> - pr " struct guestfs_lvm_vg_list *r;\n"; - pr " int i;\n"; - pr " r = malloc (sizeof (struct guestfs_lvm_vg_list));\n"; - pr " sscanf (val, \"%%d\", &r->len);\n"; - pr " r->val = calloc (r->len, sizeof (struct guestfs_lvm_vg));\n"; - pr " for (i = 0; i < r->len; ++i) {\n"; - pr " r->val[i].vg_name = malloc (16);\n"; - pr " snprintf (r->val[i].vg_name, 16, \"%%d\", i);\n"; - pr " }\n"; - pr " return r;\n" - | RLVList _ -> - pr " struct guestfs_lvm_lv_list *r;\n"; - pr " int i;\n"; - pr " r = malloc (sizeof (struct guestfs_lvm_lv_list));\n"; - pr " sscanf (val, \"%%d\", &r->len);\n"; - pr " r->val = calloc (r->len, sizeof (struct guestfs_lvm_lv));\n"; - pr " for (i = 0; i < r->len; ++i) {\n"; - pr " r->val[i].lv_name = malloc (16);\n"; - pr " snprintf (r->val[i].lv_name, 16, \"%%d\", i);\n"; - pr " }\n"; - pr " return r;\n" - | RStat _ -> - pr " struct guestfs_stat *r;\n"; - pr " r = calloc (1, sizeof (*r));\n"; - pr " sscanf (val, \"%%\" SCNi64, &r->dev);\n"; - pr " return r;\n" - | RStatVFS _ -> - pr " struct guestfs_statvfs *r;\n"; - pr " r = calloc (1, sizeof (*r));\n"; - pr " sscanf (val, \"%%\" SCNi64, &r->bsize);\n"; + pr " r->val = safe_calloc (g, r->len, sizeof *r->val);\n"; pr " return r;\n" | RHashtable _ -> pr " char **strs;\n"; pr " int n, i;\n"; pr " sscanf (val, \"%%d\", &n);\n"; - pr " strs = malloc ((n*2+1) * sizeof (char *));\n"; + pr " strs = safe_malloc (g, (n*2+1) * sizeof (*strs));\n"; pr " for (i = 0; i < n; ++i) {\n"; - pr " strs[i*2] = malloc (16);\n"; - pr " strs[i*2+1] = malloc (16);\n"; + pr " strs[i*2] = safe_malloc (g, 16);\n"; + pr " strs[i*2+1] = safe_malloc (g, 16);\n"; pr " snprintf (strs[i*2], 16, \"%%d\", i);\n"; pr " snprintf (strs[i*2+1], 16, \"%%d\", i);\n"; pr " }\n"; pr " strs[n*2] = NULL;\n"; pr " return strs;\n" - | RDirentList _ -> - pr " struct guestfs_dirent_list *r;\n"; - pr " int i;\n"; - pr " r = malloc (sizeof (struct guestfs_dirent_list));\n"; - pr " sscanf (val, \"%%d\", &r->len);\n"; - pr " r->val = calloc (r->len, sizeof (struct guestfs_dirent));\n"; - pr " for (i = 0; i < r->len; ++i)\n"; - pr " r->val[i].ino = i;\n"; - pr " return r;\n" ); pr "}\n"; pr "\n" @@ -8310,10 +7795,9 @@ print_strings (char * const* const argv) | RErr | RInt _ | RInt64 _ | RBool _ -> pr " return -1;\n" | RConstString _ - | RString _ | RStringList _ | RIntBool _ - | RPVList _ | RVGList _ | RLVList _ | RStat _ | RStatVFS _ - | RHashtable _ - | RDirentList _ -> + | RString _ | RStringList _ | RStruct _ + | RStructList _ + | RHashtable _ -> pr " return NULL;\n" ); pr "}\n"; @@ -8605,7 +8089,7 @@ let output_to filename = let () = check_functions (); - if not (Sys.file_exists "configure.ac") then ( + if not (Sys.file_exists "config.status") then ( eprintf "\ You are probably running this from the wrong directory. Run it from the top source directory using the command @@ -8722,29 +8206,14 @@ Run it from the top source directory using the command generate_java_java (); close (); - let close = output_to "java/com/redhat/et/libguestfs/PV.java" in - generate_java_struct "PV" pv_cols; - close (); - - let close = output_to "java/com/redhat/et/libguestfs/VG.java" in - generate_java_struct "VG" vg_cols; - close (); - - let close = output_to "java/com/redhat/et/libguestfs/LV.java" in - generate_java_struct "LV" lv_cols; - close (); - - let close = output_to "java/com/redhat/et/libguestfs/Stat.java" in - generate_java_struct "Stat" stat_cols; - close (); - - let close = output_to "java/com/redhat/et/libguestfs/StatVFS.java" in - generate_java_struct "StatVFS" statvfs_cols; - close (); - - let close = output_to "java/com/redhat/et/libguestfs/Dirent.java" in - generate_java_struct "Dirent" dirent_cols; - close (); + List.iter ( + fun (typ, jtyp) -> + let cols = cols_of_struct typ in + let filename = sprintf "java/com/redhat/et/libguestfs/%s.java" jtyp in + let close = output_to filename in + generate_java_struct jtyp cols; + close (); + ) java_structs; let close = output_to "java/com_redhat_et_libguestfs_GuestFS.c" in generate_java_c (); diff --git a/src/guestfs.c b/src/guestfs.c index c3bce0b..66ab12a 100644 --- a/src/guestfs.c +++ b/src/guestfs.c @@ -1,5 +1,5 @@ /* libguestfs - * Copyright (C) 2009 Red Hat Inc. + * Copyright (C) 2009 Red Hat Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -453,6 +454,42 @@ guestfs_safe_malloc (guestfs_h *g, size_t nbytes) return ptr; } +/* Return 1 if an array of N objects, each of size S, cannot exist due + to size arithmetic overflow. S must be positive and N must be + nonnegative. This is a macro, not an inline function, so that it + works correctly even when SIZE_MAX < N. + + By gnulib convention, SIZE_MAX represents overflow in size + calculations, so the conservative dividend to use here is + SIZE_MAX - 1, since SIZE_MAX might represent an overflowed value. + However, malloc (SIZE_MAX) fails on all known hosts where + sizeof (ptrdiff_t) <= sizeof (size_t), so do not bother to test for + exactly-SIZE_MAX allocations on such hosts; this avoids a test and + branch when S is known to be 1. */ +# define xalloc_oversized(n, s) \ + ((size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / (s) < (n)) + +/* Technically we should add an autoconf test for this, testing for the desired + functionality, like what's done in gnulib, but for now, this is fine. */ +#define HAVE_GNU_CALLOC (__GLIBC__ >= 2) + +/* Allocate zeroed memory for N elements of S bytes, with error + checking. S must be nonzero. */ +void * +guestfs_safe_calloc (guestfs_h *g, size_t n, size_t s) +{ + /* From gnulib's calloc function in xmalloc.c. */ + void *p; + /* Test for overflow, since some calloc implementations don't have + proper overflow checks. But omit overflow and size-zero tests if + HAVE_GNU_CALLOC, since GNU calloc catches overflow and never + returns NULL if successful. */ + if ((! HAVE_GNU_CALLOC && xalloc_oversized (n, s)) + || (! (p = calloc (n, s)) && (HAVE_GNU_CALLOC || n != 0))) + g->abort_cb (); + return p; +} + void * guestfs_safe_realloc (guestfs_h *g, void *ptr, int nbytes) { @@ -630,6 +667,17 @@ guestfs_get_memsize (guestfs_h *g) return g->memsize; } +int +guestfs_get_pid (guestfs_h *g) +{ + if (g->pid > 0) + return g->pid; + else { + error (g, "get_pid: no qemu subprocess"); + return -1; + } +} + /* Add a string to the current command line. */ static void incr_cmdline_size (guestfs_h *g) @@ -1442,44 +1490,6 @@ guestfs_end_busy (guestfs_h *g) return 0; } -/* Structure-freeing functions. These rely on the fact that the - * structure format is identical to the XDR format. See note in - * generator.ml. - */ -void -guestfs_free_int_bool (struct guestfs_int_bool *x) -{ - free (x); -} - -void -guestfs_free_lvm_pv_list (struct guestfs_lvm_pv_list *x) -{ - xdr_free ((xdrproc_t) xdr_guestfs_lvm_int_pv_list, (char *) x); - free (x); -} - -void -guestfs_free_lvm_vg_list (struct guestfs_lvm_vg_list *x) -{ - xdr_free ((xdrproc_t) xdr_guestfs_lvm_int_vg_list, (char *) x); - free (x); -} - -void -guestfs_free_lvm_lv_list (struct guestfs_lvm_lv_list *x) -{ - xdr_free ((xdrproc_t) xdr_guestfs_lvm_int_lv_list, (char *) x); - free (x); -} - -void -guestfs_free_dirent_list (struct guestfs_dirent_list *x) -{ - xdr_free ((xdrproc_t) xdr_guestfs_int_dirent_list, (char *) x); - free (x); -} - /* We don't know if stdout_event or sock_read_event will be the * first to receive EOF if the qemu process dies. This function * has the common cleanup code for both. @@ -2239,6 +2249,10 @@ guestfs__receive_file_sync (guestfs_h *g, const char *filename) char fbuf[4]; uint32_t flag = GUESTFS_CANCEL_FLAG; + if (g->verbose) + fprintf (stderr, "%s: waiting for daemon to acknowledge cancellation\n", + __func__); + xdrmem_create (&xdr, fbuf, sizeof fbuf, XDR_ENCODE); xdr_uint32_t (&xdr, &flag); xdr_destroy (&xdr); diff --git a/src/guestfs.h b/src/guestfs.h index 201d60c..f2e108b 100644 --- a/src/guestfs.h +++ b/src/guestfs.h @@ -1,5 +1,5 @@ /* libguestfs - * Copyright (C) 2009 Red Hat Inc. + * Copyright (C) 2009 Red Hat Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -52,13 +52,6 @@ extern guestfs_abort_cb guestfs_get_out_of_memory_handler (guestfs_h *g); #include #include -/* Free up return values. */ -extern void guestfs_free_int_bool (struct guestfs_int_bool *); -extern void guestfs_free_lvm_pv_list (struct guestfs_lvm_pv_list *); -extern void guestfs_free_lvm_vg_list (struct guestfs_lvm_vg_list *); -extern void guestfs_free_lvm_lv_list (struct guestfs_lvm_lv_list *); -extern void guestfs_free_dirent_list (struct guestfs_dirent_list *); - /* Low-level event API. */ typedef void (*guestfs_send_cb) (guestfs_h *g, void *data); typedef void (*guestfs_reply_cb) (guestfs_h *g, void *data, XDR *xdr); @@ -77,6 +70,7 @@ extern void guestfs_error (guestfs_h *g, const char *fs, ...) extern void guestfs_perrorf (guestfs_h *g, const char *fs, ...) __attribute__((format (printf,2,3))); extern void *guestfs_safe_malloc (guestfs_h *g, size_t nbytes); +extern void *guestfs_safe_calloc (guestfs_h *g, size_t n, size_t s); extern void *guestfs_safe_realloc (guestfs_h *g, void *ptr, int nbytes); extern char *guestfs_safe_strdup (guestfs_h *g, const char *str); extern void *guestfs_safe_memdup (guestfs_h *g, void *ptr, size_t size);