daemon: Generate the code when libraries are statically not available.

Since we as developers rarely test the case where some library is
statically not available, that side of the code was hardly tested,
except by unfortunate users in the field who often hit cases where
functions were missing or misdeclared.  In fact, when making this
change I noticed several bugs like that.

Change it so that this code is autogenerated, and therefore always
correct and up to date.

Previous code which looked like this:

  int
  optgroup_acl_available (void)
  {
    return 0;
  }

  char * __attribute__((noreturn))
  do_acl_get_file (const char *path, const char *acltype)
  {
    abort ();
  }

  /* etc */

is replaced by a single line:

  OPTGROUP_ACL_NOT_AVAILABLE
This commit is contained in:
Richard W.M. Jones
2012-12-10 16:18:39 +00:00
parent 5802b30ae5
commit 7d2ae9f30f
11 changed files with 42 additions and 411 deletions

View File

@@ -144,32 +144,6 @@ do_acl_delete_def_file (const char *dir)
#else /* no acl library */
/* Note that the wrapper code (daemon/stubs.c) ensures that the
* functions below are never called because
* optgroup_acl_available returns false.
*/
int
optgroup_acl_available (void)
{
return 0;
}
char * __attribute__((noreturn))
do_acl_get_file (const char *path, const char *acltype)
{
abort ();
}
int __attribute__((noreturn))
do_acl_set_file (const char *path, const char *acltype, const char *acl)
{
abort ();
}
int __attribute__((noreturn))
do_acl_delete_def_file (const char *dir)
{
abort ();
}
OPTGROUP_ACL_NOT_AVAILABLE
#endif /* no acl library */

View File

@@ -379,98 +379,6 @@ do_aug_ls (const char *path)
#else /* !HAVE_AUGEAS */
/* Note that the wrapper code (daemon/stubs.c) ensures that the
* functions below are never called because optgroup_augeas_available
* returns false.
*/
int
optgroup_augeas_available (void)
{
return 0;
}
int __attribute__((noreturn))
do_aug_init (const char *root, int flags)
{
abort ();
}
int __attribute__((noreturn))
do_aug_close (void)
{
abort ();
}
int __attribute__((noreturn))
do_aug_defvar (const char *name, const char *expr)
{
abort ();
}
guestfs_int_int_bool * __attribute__((noreturn))
do_aug_defnode (const char *name, const char *expr, const char *val)
{
abort ();
}
char * __attribute__((noreturn))
do_aug_get (const char *path)
{
abort ();
}
int __attribute__((noreturn))
do_aug_set (const char *path, const char *val)
{
abort ();
}
int __attribute__((noreturn))
do_aug_clear (const char *path)
{
abort ();
}
int __attribute__((noreturn))
do_aug_insert (const char *path, const char *label, int before)
{
abort ();
}
int __attribute__((noreturn))
do_aug_rm (const char *path)
{
abort ();
}
int __attribute__((noreturn))
do_aug_mv (const char *src, const char *dest)
{
abort ();
}
char ** __attribute__((noreturn))
do_aug_match (const char *path)
{
abort ();
}
int __attribute__((noreturn))
do_aug_save (void)
{
abort ();
}
int __attribute__((noreturn))
do_aug_load (void)
{
abort ();
}
char ** __attribute__((noreturn))
do_aug_ls (const char *path)
{
abort ();
}
OPTGROUP_AUGEAS_NOT_AVAILABLE
#endif

View File

@@ -106,26 +106,6 @@ do_cap_set_file (const char *path, const char *capstr)
#else /* no libcap */
/* Note that the wrapper code (daemon/stubs.c) ensures that the
* functions below are never called because
* optgroup_linuxcaps_available returns false.
*/
int
optgroup_linuxcaps_available (void)
{
return 0;
}
char * __attribute__((noreturn))
do_cap_get_file (const char *path)
{
abort ();
}
int __attribute__((noreturn))
do_cap_set_file (const char *path, const char *cap)
{
abort ();
}
OPTGROUP_LINUXCAPS_NOT_AVAILABLE
#endif /* no libcap */

View File

@@ -400,110 +400,6 @@ do_hivex_node_set_value (int64_t nodeh,
#else /* !HAVE_HIVEX */
/* Note that the wrapper code (daemon/stubs.c) ensures that the
* functions below are never called because optgroup_hivex_available
* returns false.
*/
int
optgroup_hivex_available (void)
{
return 0;
}
int __attribute__((noreturn))
do_hivex_open (const char *filename, int verbose, int debug, int write)
{
abort ();
}
int __attribute__((noreturn))
do_hivex_close (void)
{
abort ();
}
int64_t __attribute__((noreturn))
do_hivex_root (void)
{
abort ();
}
char * __attribute__((noreturn))
do_hivex_node_name (int64_t nodeh)
{
abort ();
}
guestfs_int_hivex_node_list * __attribute__((noreturn))
do_hivex_node_children (int64_t nodeh)
{
abort ();
}
int64_t __attribute__((noreturn))
do_hivex_node_get_child (int64_t nodeh, const char *name)
{
abort ();
}
int64_t __attribute__((noreturn))
do_hivex_node_parent (int64_t nodeh)
{
abort ();
}
guestfs_int_hivex_value_list * __attribute__((noreturn))
do_hivex_node_values (int64_t nodeh)
{
abort ();
}
int64_t __attribute__((noreturn))
do_hivex_node_get_value (int64_t nodeh, const char *key)
{
abort ();
}
char * __attribute__((noreturn))
do_hivex_value_key (int64_t valueh)
{
abort ();
}
int64_t __attribute__((noreturn))
do_hivex_value_type (int64_t valueh)
{
abort ();
}
char * __attribute__((noreturn))
do_hivex_value_value (int64_t valueh, size_t *size_r)
{
abort ();
}
int __attribute__((noreturn))
do_hivex_commit (const char *filename)
{
abort ();
}
int64_t __attribute__((noreturn))
do_hivex_node_add_child (int64_t parent, const char *name)
{
abort ();
}
int __attribute__((noreturn))
do_hivex_node_delete_child (int64_t nodeh)
{
abort ();
}
int __attribute__((noreturn))
do_hivex_node_set_value (int64_t nodeh, const char *key, int64_t t, const char *val, size_t val_size)
{
abort ();
}
OPTGROUP_HIVEX_NOT_AVAILABLE
#endif /* !HAVE_HIVEX */

View File

@@ -388,50 +388,6 @@ do_inotify_files (void)
#else /* !HAVE_SYS_INOTIFY_H */
/* Note that the wrapper code (daemon/stubs.c) ensures that the
* functions below are never called because optgroup_inotify_available
* returns false.
*/
int
optgroup_inotify_available (void)
{
return 0;
}
int
do_inotify_init (int max_events)
{
abort ();
}
int
do_inotify_close (void)
{
abort ();
}
int64_t
do_inotify_add_watch (const char *path, int mask)
{
abort ();
}
int
do_inotify_rm_watch (int wd)
{
abort ();
}
guestfs_int_inotify_event_list *
do_inotify_read (void)
{
abort ();
}
char **
do_inotify_files (void)
{
abort ();
}
OPTGROUP_INOTIFY_NOT_AVAILABLE
#endif

View File

@@ -80,34 +80,6 @@ do_mknod_c (int mode, int devmajor, int devminor, const char *path)
#else
int
optgroup_mknod_available (void)
{
return 0;
}
int
do_mknod (int mode, int devmajor, int devminor, const char *path)
{
abort ();
}
int
do_mkfifo (int mode, const char *path)
{
abort ();
}
int
do_mknod_b (int mode, int devmajor, int devminor, const char *path)
{
abort ();
}
int
do_mknod_c (int mode, int devmajor, int devminor, const char *path)
{
abort ();
}
OPTGROUP_MKNOD_NOT_AVAILABLE
#endif

View File

@@ -64,17 +64,7 @@ do_realpath (const char *path)
#else /* !HAVE_REALPATH */
int
optgroup_realpath_available (void)
{
return 0;
}
char *
do_realpath (const char *path)
{
abort ();
}
OPTGROUP_REALPATH_NOT_AVAILABLE
#endif /* !HAVE_REALPATH */

View File

@@ -87,22 +87,6 @@ do_getcon (void)
#else /* !HAVE_LIBSELINUX */
int
optgroup_selinux_available (void)
{
return 0;
}
int __attribute__((noreturn))
do_setcon (const char *context)
{
abort ();
}
char * __attribute__((noreturn))
do_getcon (void)
{
abort ();
}
OPTGROUP_SELINUX_NOT_AVAILABLE
#endif /* !HAVE_LIBSELINUX */

View File

@@ -541,68 +541,6 @@ do_lgetxattr (const char *path, const char *name, size_t *size_r)
#else /* no xattr.h */
/* Note that the wrapper code (daemon/stubs.c) ensures that the
* functions below are never called because
* optgroup_linuxxattrs_available returns false.
*/
int
optgroup_linuxxattrs_available (void)
{
return 0;
}
guestfs_int_xattr_list *
do_getxattrs (const char *path)
{
abort ();
}
guestfs_int_xattr_list *
do_lgetxattrs (const char *path)
{
abort ();
}
int
do_setxattr (const char *xattr, const char *val, int vallen, const char *path)
{
abort ();
}
int
do_lsetxattr (const char *xattr, const char *val, int vallen, const char *path)
{
abort ();
}
int
do_removexattr (const char *xattr, const char *path)
{
abort ();
}
int
do_lremovexattr (const char *xattr, const char *path)
{
abort ();
}
guestfs_int_xattr_list *
do_internal_lxattrlist (const char *path, char *const *names)
{
abort ();
}
char *
do_getxattr (const char *path, const char *name, size_t *size_r)
{
abort ();
}
char *
do_lgetxattr (const char *path, const char *name, size_t *size_r)
{
abort ();
}
OPTGROUP_LINUXXATTRS_NOT_AVAILABLE
#endif /* no xattr.h */

View File

@@ -50,6 +50,7 @@ let rec generate_prototype ?(extern = true) ?(static = false)
?(single_line = false) ?(indent = "") ?(newline = false)
?(in_daemon = false)
?(dll_public = false)
?(attribute_noreturn = false)
?(prefix = "") ?(suffix = "")
?handle
?(optarg_proto = Dots)
@@ -82,6 +83,7 @@ let rec generate_prototype ?(extern = true) ?(static = false)
else pr "guestfs_int_%s_list *" typ
);
if single_line && !space then pr " ";
if attribute_noreturn then pr "__attribute__((noreturn)) ";
if not single_line then pr "\n%s" indent;
let is_RBufferOut = match ret with RBufferOut _ -> true | _ -> false in
pr "%s%s%s (" prefix name suffix;

View File

@@ -590,4 +590,35 @@ and generate_daemon_optgroups_h () =
) optgroups;
pr "\n";
pr "\
/* These macros can be used to disable an entire group of functions.
* The advantage of generating this code is that it avoids an
* undetected error when a new function in a group is added, but
* the appropriate abort function is not added to the daemon (because
* the developers rarely test that the daemon builds when a library
* is not present).
*/
";
List.iter (
fun (group, fns) ->
pr "#define OPTGROUP_%s_NOT_AVAILABLE \\\n" (String.uppercase group);
List.iter (
fun { name = name; style = ret, args, optargs } ->
let style = ret, args @ args_of_optargs optargs, [] in
pr " ";
generate_prototype
~prefix:"do_"
~attribute_noreturn:true
~single_line:true ~newline:false
~extern:false ~in_daemon:true
~semicolon:false
name style;
pr " { abort (); } \\\n"
) fns;
pr " int optgroup_%s_available (void) { return 0; }\n" group;
pr "\n"
) optgroups;
pr "#endif /* GUESTFSD_OPTGROUPS_H */\n"