We also need to be more careful about PyString_FromString and similar
functions returning NULL on failure. Currently we don't check this
every time. This commit adds more checks, but is still not complete.
libguestfs has used double and triple underscores in identifiers.
These aren't valid for global names in C++.
The first step is to replace all guestfs___* (3 underscores) with
guestfs_int_*. We've used guestfs_int_* elsewhere already as a prefix
for internal identifiers.
This is an entirely mechanical change done using:
git ls-files | xargs perl -pi.bak -e 's/guestfs___/guestfs_int_/g'
Reference: http://stackoverflow.com/a/228797
This allows the Python binding of guestfs_add_libvirt_dom to work.
There is a regression test to ensure this keeps working.
Note this requires a patched libvirt-python, supporting the
c_pointer() method.
This implements Pointer arguments properly, at least for certain
limited definitions of "implements" and "properly".
'Pointer' as an argument type is meant to indicate a pointer passed to
an API. The canonical example is the following proposed API:
int guestfs_add_libvirt_dom (guestfs_h *g, virDomainPtr dom, ...);
where 'dom' is described in the generator as:
Pointer ("virDomainPtr", "dom")
Pointer existed already in the generator, but the implementation was
broken. It is not used by any existing API.
There are two basic difficulties of implementing Pointer:
(1) In language bindings there is no portable way to turn (eg.) a Perl
Sys::Virt 'dom' object into a C virDomainPtr.
(2) We can't rely on <libvirt/libvirt.h> being included (since it's an
optional dependency).
In this commit, we solve (2) by using a 'void *'.
We don't solve (1), really. Instead we have a macro
POINTER_NOT_IMPLEMENTED which is used by currently all the non-C
language bindings. It complains loudly and passes a NULL to the
underlying function. The underlying function detects the NULL and
safely returns an error. It is to be hoped that people will
contribute patches to make each language binding work, although in
some bindings it will always remain impossible to implement.
When using optional arguments of type OStringList, the code free'ing
the member in the optargs_s struct corresponding to that optional
argument would just check for a non-PyNone PyObject for that argument.
If before that optional argument there are other arguments which can
cause an earlier error return from that binding function, the free'ing
code will then act on garbage values.
Enhance the check by also checking whether the optargs struct has the
bitmask with the element for that argument, meaning that the
corresponding struct member was initialized.
Look for use of external_functions and fish_functions and replace with
use of external_functions_sorted and fish_functions_sorted where
possible. This ensures that the output of the generator is sorted as
far as possible.
I also checked for uses of internal_functions and documented_functions
but those are not used. The *_sorted versions are always used
instead.
The visibility field in action replaces in_fish, in_docs and internal.
The defined types are:
VPublic:
A public API. This is exported and documented in all language
bindings, and in guestfish.
VStateTest:
A public API which queries the library state machine. It is exported
and documented in all language bindings, but not guestfish.
VBindTest:
An internal API used only for testing language bindings. It is
guarded by GUESTFS_PRIVATE in the C api, but exported by all other
language bindings as it is required for testing. If language
bindings offer any way to guard use of these apis, that mechanism
should be used. It is not documented anywhere.
VDebug:
A debugging API. It is exported by all language bindings, and in
guestfish, but is not documented anywhere.
VInternal:
An internal-only API. It is guarded by GUESTFS_PRIVATE in the C api,
and not exported at all in any other language binding. It is not
documented anywhere.
Certain functions are intended to be internal only, but we currently
export them anyway. This change moves them into a separate section of
guestfs.h protected by a GUESTFS_PRIVATE variable. This change also
enables private structs, but doesn't implement any.
This change only affects the C api. Language bindings aren't affected,
but probably should be in the future.
In languages like Python where we release a global lock around
long-running libguestfs functions, it is also useful to *not* release
this lock for small, non-blocking functions.
Therefore mark all functions with a 'blocking' boolean flag. It
defaults to true, and is true by definition for all daemon functions.
For non-daemon functions, I have classified them manually.
Only when the blocking flag is set do we generate the code to release
and reacquire the lock around libguestfs calls.
guestfs_parse_environment_list.
Add a new function for creating a handle:
guestfs_h *guestfs_create_flags (unsigned flags [, ...]);
This variant lets you supply flags and extra arguments, although extra
arguments are not used at the moment.
Of particular interest is the ability to separate the creation of the
handle from the parsing of environment variables like
LIBGUESTFS_DEBUG. guestfs_create does both together, which prevents
us from propagating errors from parsing environment variables back to
the caller (guestfs_create has always printed any errors on stderr and
then just ignored them).
If you are interested in these errors, you can now write:
g = guestfs_create_flags (GUESTFS_CREATE_NO_ENVIRONMENT);
if (!g)
exit (EXIT_FAILURE);
r = guestfs_parse_environment (g);
if (!r)
exit (EXIT_FAILURE);
Also you can *omit* the call to guestfs_parse_environment, which
creates a handle unaffected by the environment (which was not possible
before).
This commit also includes new (backwards compatible) changes to the
OCaml, Perl, Python, Ruby and Java constructors that let you use the
flags.
This is a simple renaming of the files/modules.
Note that in OCaml, module names are derived from filenames by
capitalizing the first letter. Thus the old module names had the form
"Generator_api_versions". The new modules names have the form
"Api_versions".