lib: Split up huge src/guestfs.c into logical compilation units.

This file had grown by accretion to include:

 - code related to handles (now in src/handle.c)

 - safe allocation (src/alloc.c)

 - debug, errors, warnings (src/errors.c)

 - private data (src/private-data.c)

 - miscellaneous functions (src/canonical-name.c, src/utils.c)

This commit also removes about a dozen #include files which were
probably not really used.

This is just code motion.
This commit is contained in:
Richard W.M. Jones
2012-11-12 12:56:39 +00:00
parent f9ab256f0e
commit 02ecd048d3
9 changed files with 675 additions and 541 deletions

View File

@@ -225,18 +225,21 @@ src/actions-5.c
src/actions-6.c
src/actions-support.c
src/actions-variants.c
src/alloc.c
src/appliance.c
src/bindtests.c
src/canonical-name.c
src/command.c
src/dbdump.c
src/errnostring-gperf.c
src/errnostring.c
src/errors.c
src/events.c
src/file.c
src/filearch.c
src/free-structs.c
src/fuse.c
src/guestfs.c
src/handle.c
src/info.c
src/inspect-apps.c
src/inspect-fs-cd.c
@@ -253,8 +256,10 @@ src/libvirt-auth.c
src/libvirt-domain.c
src/listfs.c
src/match.c
src/private-data.c
src/proto.c
src/tmpdirs.c
src/utils.c
test-tool/test-tool.c
tools/virt-list-filesystems.pl
tools/virt-list-partitions.pl

View File

@@ -126,7 +126,6 @@ libguestfs_la_LDFLAGS = -version-info $(MAX_PROC_NR):0:$(MAX_PROC_NR)
libguestfs_la_LDFLAGS += $(VERSION_SCRIPT_FLAGS)$(srcdir)/libguestfs.syms
libguestfs_la_SOURCES = \
guestfs.c \
guestfs.h \
guestfs-internal.h \
guestfs_protocol.h \
@@ -139,15 +138,19 @@ libguestfs_la_SOURCES = \
actions-6.c \
actions-support.c \
actions-variants.c \
alloc.c \
appliance.c \
bindtests.c \
command.c \
canonical-name.c \
dbdump.c \
errors.c \
events.c \
file.c \
filearch.c \
free-structs.c \
fuse.c \
handle.c \
info.c \
inspect.c \
inspect-apps.c \
@@ -164,8 +167,10 @@ libguestfs_la_SOURCES = \
libvirt-domain.c \
listfs.c \
match.c \
private-data.c \
proto.c \
tmpdirs.c \
utils.c \
libguestfs.syms
libguestfs_la_LIBADD = \

124
src/alloc.c Normal file
View File

@@ -0,0 +1,124 @@
/* libguestfs
* Copyright (C) 2009-2012 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
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "guestfs.h"
#include "guestfs-internal.h"
void *
guestfs_safe_malloc (guestfs_h *g, size_t nbytes)
{
void *ptr = malloc (nbytes);
if (nbytes > 0 && !ptr) g->abort_cb ();
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. */
#if defined(__GLIBC__)
#define HAVE_GNU_CALLOC (__GLIBC__ >= 2)
#else
#define HAVE_GNU_CALLOC 0
#endif
/* 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, size_t nbytes)
{
void *p = realloc (ptr, nbytes);
if (nbytes > 0 && !p) g->abort_cb ();
return p;
}
char *
guestfs_safe_strdup (guestfs_h *g, const char *str)
{
char *s = strdup (str);
if (!s) g->abort_cb ();
return s;
}
char *
guestfs_safe_strndup (guestfs_h *g, const char *str, size_t n)
{
char *s = strndup (str, n);
if (!s) g->abort_cb ();
return s;
}
void *
guestfs_safe_memdup (guestfs_h *g, const void *ptr, size_t size)
{
void *p = malloc (size);
if (!p) g->abort_cb ();
memcpy (p, ptr, size);
return p;
}
char *
guestfs_safe_asprintf (guestfs_h *g, const char *fs, ...)
{
va_list args;
char *msg;
va_start (args, fs);
int err = vasprintf (&msg, fs, args);
va_end (args);
if (err == -1)
g->abort_cb ();
return msg;
}

50
src/canonical-name.c Normal file
View File

@@ -0,0 +1,50 @@
/* libguestfs
* Copyright (C) 2009-2012 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
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "guestfs.h"
#include "guestfs-internal.h"
#include "guestfs-internal-actions.h"
char *
guestfs__canonical_device_name (guestfs_h *g, const char *device)
{
char *ret;
if (STRPREFIX (device, "/dev/hd") ||
STRPREFIX (device, "/dev/vd")) {
ret = safe_strdup (g, device);
ret[5] = 's';
}
else if (STRPREFIX (device, "/dev/mapper/") ||
STRPREFIX (device, "/dev/dm-")) {
/* XXX hide errors */
ret = guestfs_lvm_canonical_lv_name (g, device);
if (ret == NULL)
ret = safe_strdup (g, device);
}
else
ret = safe_strdup (g, device);
return ret; /* caller frees */
}

282
src/errors.c Normal file
View File

@@ -0,0 +1,282 @@
/* libguestfs
* Copyright (C) 2009-2012 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
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#include "c-ctype.h"
#include "guestfs.h"
#include "guestfs-internal.h"
const char *
guestfs_last_error (guestfs_h *g)
{
return g->last_error;
}
int
guestfs_last_errno (guestfs_h *g)
{
return g->last_errnum;
}
static void
set_last_error (guestfs_h *g, int errnum, const char *msg)
{
free (g->last_error);
g->last_error = strdup (msg);
g->last_errnum = errnum;
}
/* Warning are printed unconditionally. We try to make these rare.
* Generally speaking, a warning should either be an error, or if it's
* not important for end users then it should be a debug message.
*/
void
guestfs___warning (guestfs_h *g, const char *fs, ...)
{
va_list args;
char *msg, *msg2;
int len;
va_start (args, fs);
len = vasprintf (&msg, fs, args);
va_end (args);
if (len < 0) return;
len = asprintf (&msg2, _("warning: %s"), msg);
free (msg);
if (len < 0) return;
guestfs___call_callbacks_message (g, GUESTFS_EVENT_LIBRARY, msg2, len);
free (msg2);
}
/* Debug messages. */
void
guestfs___debug (guestfs_h *g, const char *fs, ...)
{
va_list args;
char *msg;
int len;
/* The cpp macro "debug" has already checked that g->verbose is true
* before calling this function, but we check it again just in case
* anyone calls this function directly.
*/
if (!g->verbose)
return;
va_start (args, fs);
len = vasprintf (&msg, fs, args);
va_end (args);
if (len < 0) return;
guestfs___call_callbacks_message (g, GUESTFS_EVENT_LIBRARY, msg, len);
free (msg);
}
/* Call trace messages. These are enabled by setting g->trace, and
* calls to this function should only happen from the generated code
* in src/actions.c
*/
void
guestfs___trace (guestfs_h *g, const char *fs, ...)
{
va_list args;
char *msg;
int len;
va_start (args, fs);
len = vasprintf (&msg, fs, args);
va_end (args);
if (len < 0) return;
guestfs___call_callbacks_message (g, GUESTFS_EVENT_TRACE, msg, len);
free (msg);
}
void
guestfs_error_errno (guestfs_h *g, int errnum, const char *fs, ...)
{
va_list args;
char *msg;
va_start (args, fs);
int err = vasprintf (&msg, fs, args);
va_end (args);
if (err < 0) return;
/* set_last_error first so that the callback can access the error
* message and errno through the handle if it wishes.
*/
set_last_error (g, errnum, msg);
if (g->error_cb) g->error_cb (g, g->error_cb_data, msg);
free (msg);
}
void
guestfs_perrorf (guestfs_h *g, const char *fs, ...)
{
va_list args;
char *msg;
int errnum = errno;
va_start (args, fs);
int err = vasprintf (&msg, fs, args);
va_end (args);
if (err < 0) return;
char buf[256];
strerror_r (errnum, buf, sizeof buf);
msg = safe_realloc (g, msg, strlen (msg) + 2 + strlen (buf) + 1);
strcat (msg, ": ");
strcat (msg, buf);
/* set_last_error first so that the callback can access the error
* message and errno through the handle if it wishes.
*/
set_last_error (g, errnum, msg);
if (g->error_cb) g->error_cb (g, g->error_cb_data, msg);
free (msg);
}
void
guestfs_set_out_of_memory_handler (guestfs_h *g, guestfs_abort_cb cb)
{
g->abort_cb = cb;
}
guestfs_abort_cb
guestfs_get_out_of_memory_handler (guestfs_h *g)
{
return g->abort_cb;
}
void
guestfs_set_error_handler (guestfs_h *g,
guestfs_error_handler_cb cb, void *data)
{
g->error_cb = cb;
g->error_cb_data = data;
}
guestfs_error_handler_cb
guestfs_get_error_handler (guestfs_h *g, void **data_rtn)
{
if (data_rtn) *data_rtn = g->error_cb_data;
return g->error_cb;
}
void
guestfs_push_error_handler (guestfs_h *g,
guestfs_error_handler_cb cb, void *data)
{
struct error_cb_stack *old_stack;
old_stack = g->error_cb_stack;
g->error_cb_stack = safe_malloc (g, sizeof (struct error_cb_stack));
g->error_cb_stack->next = old_stack;
g->error_cb_stack->error_cb = g->error_cb;
g->error_cb_stack->error_cb_data = g->error_cb_data;
guestfs_set_error_handler (g, cb, data);
}
void
guestfs_pop_error_handler (guestfs_h *g)
{
struct error_cb_stack *next_stack;
if (g->error_cb_stack) {
next_stack = g->error_cb_stack->next;
guestfs_set_error_handler (g, g->error_cb_stack->error_cb,
g->error_cb_stack->error_cb_data);
free (g->error_cb_stack);
g->error_cb_stack = next_stack;
}
else
guestfs___init_error_handler (g);
}
static void default_error_cb (guestfs_h *g, void *data, const char *msg);
void
guestfs___init_error_handler (guestfs_h *g)
{
g->error_cb = default_error_cb;
g->error_cb_data = NULL;
}
static void
default_error_cb (guestfs_h *g, void *data, const char *msg)
{
fprintf (stderr, _("libguestfs: error: %s\n"), msg);
}
/* When tracing, be careful how we print BufferIn parameters which
* usually contain large amounts of binary data (RHBZ#646822).
*/
void
guestfs___print_BufferIn (FILE *out, const char *buf, size_t buf_size)
{
size_t i;
size_t orig_size = buf_size;
if (buf_size > 256)
buf_size = 256;
fputc ('"', out);
for (i = 0; i < buf_size; ++i) {
if (c_isprint (buf[i]))
fputc (buf[i], out);
else
fprintf (out, "\\x%02x", (unsigned char) buf[i]);
}
fputc ('"', out);
if (orig_size > buf_size)
fprintf (out,
_("<truncated, original size %zu bytes>"), orig_size);
}
void
guestfs___print_BufferOut (FILE *out, const char *buf, size_t buf_size)
{
guestfs___print_BufferIn (out, buf, buf_size);
}

View File

@@ -472,14 +472,7 @@ struct guestfs_message_header;
struct guestfs_message_error;
struct guestfs_progress;
/* guestfs.c */
extern void guestfs_error (guestfs_h *g, const char *fs, ...)
__attribute__((format (printf,2,3)));
extern void guestfs_error_errno (guestfs_h *g, int errnum, const char *fs, ...)
__attribute__((format (printf,3,4)));
extern void guestfs_perrorf (guestfs_h *g, const char *fs, ...)
__attribute__((format (printf,2,3)));
/* alloc.c */
extern void *guestfs_safe_realloc (guestfs_h *g, void *ptr, size_t nbytes);
extern char *guestfs_safe_strdup (guestfs_h *g, const char *str);
extern char *guestfs_safe_strndup (guestfs_h *g, const char *str, size_t n);
@@ -487,6 +480,24 @@ extern void *guestfs_safe_memdup (guestfs_h *g, const void *ptr, size_t size);
extern char *guestfs_safe_asprintf (guestfs_h *g, const char *fs, ...)
__attribute__((format (printf,2,3)));
#define safe_calloc guestfs_safe_calloc
#define safe_malloc guestfs_safe_malloc
#define safe_realloc guestfs_safe_realloc
#define safe_strdup guestfs_safe_strdup
#define safe_strndup guestfs_safe_strndup
#define safe_memdup guestfs_safe_memdup
#define safe_asprintf guestfs_safe_asprintf
/* errors.c */
extern void guestfs___init_error_handler (guestfs_h *g);
extern void guestfs_error (guestfs_h *g, const char *fs, ...)
__attribute__((format (printf,2,3)));
extern void guestfs_error_errno (guestfs_h *g, int errnum, const char *fs, ...)
__attribute__((format (printf,3,4)));
extern void guestfs_perrorf (guestfs_h *g, const char *fs, ...)
__attribute__((format (printf,2,3)));
extern void guestfs___warning (guestfs_h *g, const char *fs, ...)
__attribute__((format (printf,2,3)));
extern void guestfs___debug (guestfs_h *g, const char *fs, ...)
@@ -494,8 +505,6 @@ extern void guestfs___debug (guestfs_h *g, const char *fs, ...)
extern void guestfs___trace (guestfs_h *g, const char *fs, ...)
__attribute__((format (printf,2,3)));
extern void guestfs___free_string_list (char **);
extern void guestfs___print_BufferIn (FILE *out, const char *buf, size_t buf_size);
extern void guestfs___print_BufferOut (FILE *out, const char *buf, size_t buf_size);
@@ -504,13 +513,9 @@ extern void guestfs___print_BufferOut (FILE *out, const char *buf, size_t buf_si
#define warning(g,...) guestfs___warning((g),__VA_ARGS__)
#define debug(g,...) \
do { if ((g)->verbose) guestfs___debug ((g),__VA_ARGS__); } while (0)
#define safe_calloc guestfs_safe_calloc
#define safe_malloc guestfs_safe_malloc
#define safe_realloc guestfs_safe_realloc
#define safe_strdup guestfs_safe_strdup
#define safe_strndup guestfs_safe_strndup
#define safe_memdup guestfs_safe_memdup
#define safe_asprintf guestfs_safe_asprintf
/* utils.c */
extern void guestfs___free_string_list (char **);
/* actions-support.c */
extern int guestfs___check_reply_header (guestfs_h *g, const struct guestfs_message_header *hdr, unsigned int proc_nr, unsigned int serial);

View File

@@ -18,29 +18,10 @@
#include <config.h>
#define _BSD_SOURCE /* for mkdtemp, usleep */
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
#include <inttypes.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <time.h>
#include <assert.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
#include <sys/wait.h>
#include <rpc/types.h>
#include <rpc/xdr.h>
#ifdef HAVE_LIBVIRT
#include <libvirt/libvirt.h>
@@ -51,10 +32,7 @@
#include <libxml/xmlversion.h>
#endif
#include "c-ctype.h"
#include "glthread/lock.h"
#include "hash.h"
#include "hash-pjw.h"
#include "guestfs.h"
#include "guestfs-internal.h"
@@ -62,7 +40,6 @@
#include "guestfs_protocol.h"
static int parse_attach_method (guestfs_h *g, const char *method);
static void init_error_handler (guestfs_h *g);
static int shutdown_backend (guestfs_h *g, int check_for_errors);
static void close_handles (void);
@@ -117,7 +94,7 @@ guestfs_create_flags (unsigned flags, ...)
g->fd[1] = -1;
g->sock = -1;
init_error_handler (g);
guestfs___init_error_handler (g);
g->abort_cb = abort;
g->recovery_proc = 1;
@@ -410,321 +387,6 @@ close_handles (void)
while (handles) guestfs_close (handles);
}
const char *
guestfs_last_error (guestfs_h *g)
{
return g->last_error;
}
int
guestfs_last_errno (guestfs_h *g)
{
return g->last_errnum;
}
static void
set_last_error (guestfs_h *g, int errnum, const char *msg)
{
free (g->last_error);
g->last_error = strdup (msg);
g->last_errnum = errnum;
}
/* Warning are printed unconditionally. We try to make these rare.
* Generally speaking, a warning should either be an error, or if it's
* not important for end users then it should be a debug message.
*/
void
guestfs___warning (guestfs_h *g, const char *fs, ...)
{
va_list args;
char *msg, *msg2;
int len;
va_start (args, fs);
len = vasprintf (&msg, fs, args);
va_end (args);
if (len < 0) return;
len = asprintf (&msg2, _("warning: %s"), msg);
free (msg);
if (len < 0) return;
guestfs___call_callbacks_message (g, GUESTFS_EVENT_LIBRARY, msg2, len);
free (msg2);
}
/* Debug messages. */
void
guestfs___debug (guestfs_h *g, const char *fs, ...)
{
va_list args;
char *msg;
int len;
/* The cpp macro "debug" has already checked that g->verbose is true
* before calling this function, but we check it again just in case
* anyone calls this function directly.
*/
if (!g->verbose)
return;
va_start (args, fs);
len = vasprintf (&msg, fs, args);
va_end (args);
if (len < 0) return;
guestfs___call_callbacks_message (g, GUESTFS_EVENT_LIBRARY, msg, len);
free (msg);
}
/* Call trace messages. These are enabled by setting g->trace, and
* calls to this function should only happen from the generated code
* in src/actions.c
*/
void
guestfs___trace (guestfs_h *g, const char *fs, ...)
{
va_list args;
char *msg;
int len;
va_start (args, fs);
len = vasprintf (&msg, fs, args);
va_end (args);
if (len < 0) return;
guestfs___call_callbacks_message (g, GUESTFS_EVENT_TRACE, msg, len);
free (msg);
}
void
guestfs_error_errno (guestfs_h *g, int errnum, const char *fs, ...)
{
va_list args;
char *msg;
va_start (args, fs);
int err = vasprintf (&msg, fs, args);
va_end (args);
if (err < 0) return;
/* set_last_error first so that the callback can access the error
* message and errno through the handle if it wishes.
*/
set_last_error (g, errnum, msg);
if (g->error_cb) g->error_cb (g, g->error_cb_data, msg);
free (msg);
}
void
guestfs_perrorf (guestfs_h *g, const char *fs, ...)
{
va_list args;
char *msg;
int errnum = errno;
va_start (args, fs);
int err = vasprintf (&msg, fs, args);
va_end (args);
if (err < 0) return;
char buf[256];
strerror_r (errnum, buf, sizeof buf);
msg = safe_realloc (g, msg, strlen (msg) + 2 + strlen (buf) + 1);
strcat (msg, ": ");
strcat (msg, buf);
/* set_last_error first so that the callback can access the error
* message and errno through the handle if it wishes.
*/
set_last_error (g, errnum, msg);
if (g->error_cb) g->error_cb (g, g->error_cb_data, msg);
free (msg);
}
void *
guestfs_safe_malloc (guestfs_h *g, size_t nbytes)
{
void *ptr = malloc (nbytes);
if (nbytes > 0 && !ptr) g->abort_cb ();
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. */
#if defined(__GLIBC__)
#define HAVE_GNU_CALLOC (__GLIBC__ >= 2)
#else
#define HAVE_GNU_CALLOC 0
#endif
/* 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, size_t nbytes)
{
void *p = realloc (ptr, nbytes);
if (nbytes > 0 && !p) g->abort_cb ();
return p;
}
char *
guestfs_safe_strdup (guestfs_h *g, const char *str)
{
char *s = strdup (str);
if (!s) g->abort_cb ();
return s;
}
char *
guestfs_safe_strndup (guestfs_h *g, const char *str, size_t n)
{
char *s = strndup (str, n);
if (!s) g->abort_cb ();
return s;
}
void *
guestfs_safe_memdup (guestfs_h *g, const void *ptr, size_t size)
{
void *p = malloc (size);
if (!p) g->abort_cb ();
memcpy (p, ptr, size);
return p;
}
char *
guestfs_safe_asprintf (guestfs_h *g, const char *fs, ...)
{
va_list args;
char *msg;
va_start (args, fs);
int err = vasprintf (&msg, fs, args);
va_end (args);
if (err == -1)
g->abort_cb ();
return msg;
}
void
guestfs_set_out_of_memory_handler (guestfs_h *g, guestfs_abort_cb cb)
{
g->abort_cb = cb;
}
guestfs_abort_cb
guestfs_get_out_of_memory_handler (guestfs_h *g)
{
return g->abort_cb;
}
void
guestfs_set_error_handler (guestfs_h *g,
guestfs_error_handler_cb cb, void *data)
{
g->error_cb = cb;
g->error_cb_data = data;
}
guestfs_error_handler_cb
guestfs_get_error_handler (guestfs_h *g, void **data_rtn)
{
if (data_rtn) *data_rtn = g->error_cb_data;
return g->error_cb;
}
void
guestfs_push_error_handler (guestfs_h *g,
guestfs_error_handler_cb cb, void *data)
{
struct error_cb_stack *old_stack;
old_stack = g->error_cb_stack;
g->error_cb_stack = safe_malloc (g, sizeof (struct error_cb_stack));
g->error_cb_stack->next = old_stack;
g->error_cb_stack->error_cb = g->error_cb;
g->error_cb_stack->error_cb_data = g->error_cb_data;
guestfs_set_error_handler (g, cb, data);
}
void
guestfs_pop_error_handler (guestfs_h *g)
{
struct error_cb_stack *next_stack;
if (g->error_cb_stack) {
next_stack = g->error_cb_stack->next;
guestfs_set_error_handler (g, g->error_cb_stack->error_cb,
g->error_cb_stack->error_cb_data);
free (g->error_cb_stack);
g->error_cb_stack = next_stack;
}
else
init_error_handler (g);
}
static void default_error_cb (guestfs_h *g, void *data, const char *msg);
static void
init_error_handler (guestfs_h *g)
{
g->error_cb = default_error_cb;
g->error_cb_data = NULL;
}
static void
default_error_cb (guestfs_h *g, void *data, const char *msg)
{
fprintf (stderr, _("libguestfs: error: %s\n"), msg);
}
void
guestfs_user_cancel (guestfs_h *g)
{
@@ -1005,186 +667,3 @@ guestfs__get_smp (guestfs_h *g)
{
return g->smp;
}
/* Note the private data area is allocated lazily, since the vast
* majority of callers will never use it. This means g->pda is
* likely to be NULL.
*/
struct pda_entry {
char *key; /* key */
void *data; /* opaque user data pointer */
};
static size_t
hasher (void const *x, size_t table_size)
{
struct pda_entry const *p = x;
return hash_pjw (p->key, table_size);
}
static bool
comparator (void const *x, void const *y)
{
struct pda_entry const *a = x;
struct pda_entry const *b = y;
return STREQ (a->key, b->key);
}
static void
freer (void *x)
{
if (x) {
struct pda_entry *p = x;
free (p->key);
free (p);
}
}
void
guestfs_set_private (guestfs_h *g, const char *key, void *data)
{
if (g->pda == NULL) {
g->pda = hash_initialize (16, NULL, hasher, comparator, freer);
if (g->pda == NULL)
g->abort_cb ();
}
struct pda_entry *new_entry = safe_malloc (g, sizeof *new_entry);
new_entry->key = safe_strdup (g, key);
new_entry->data = data;
struct pda_entry *old_entry = hash_delete (g->pda, new_entry);
freer (old_entry);
struct pda_entry *entry = hash_insert (g->pda, new_entry);
if (entry == NULL)
g->abort_cb ();
assert (entry == new_entry);
}
static inline char *
bad_cast (char const *s)
{
return (char *) s;
}
void *
guestfs_get_private (guestfs_h *g, const char *key)
{
if (g->pda == NULL)
return NULL; /* no keys have been set */
const struct pda_entry k = { .key = bad_cast (key) };
struct pda_entry *entry = hash_lookup (g->pda, &k);
if (entry)
return entry->data;
else
return NULL;
}
/* Iterator. */
void *
guestfs_first_private (guestfs_h *g, const char **key_rtn)
{
if (g->pda == NULL)
return NULL;
g->pda_next = hash_get_first (g->pda);
/* Ignore any keys with NULL data pointers. */
while (g->pda_next && g->pda_next->data == NULL)
g->pda_next = hash_get_next (g->pda, g->pda_next);
if (g->pda_next == NULL)
return NULL;
*key_rtn = g->pda_next->key;
return g->pda_next->data;
}
void *
guestfs_next_private (guestfs_h *g, const char **key_rtn)
{
if (g->pda == NULL)
return NULL;
if (g->pda_next == NULL)
return NULL;
/* Walk to the next key with a non-NULL data pointer. */
do {
g->pda_next = hash_get_next (g->pda, g->pda_next);
} while (g->pda_next && g->pda_next->data == NULL);
if (g->pda_next == NULL)
return NULL;
*key_rtn = g->pda_next->key;
return g->pda_next->data;
}
/* When tracing, be careful how we print BufferIn parameters which
* usually contain large amounts of binary data (RHBZ#646822).
*/
void
guestfs___print_BufferIn (FILE *out, const char *buf, size_t buf_size)
{
size_t i;
size_t orig_size = buf_size;
if (buf_size > 256)
buf_size = 256;
fputc ('"', out);
for (i = 0; i < buf_size; ++i) {
if (c_isprint (buf[i]))
fputc (buf[i], out);
else
fprintf (out, "\\x%02x", (unsigned char) buf[i]);
}
fputc ('"', out);
if (orig_size > buf_size)
fprintf (out,
_("<truncated, original size %zu bytes>"), orig_size);
}
void
guestfs___print_BufferOut (FILE *out, const char *buf, size_t buf_size)
{
guestfs___print_BufferIn (out, buf, buf_size);
}
void
guestfs___free_string_list (char **argv)
{
size_t i;
for (i = 0; argv[i] != NULL; ++i)
free (argv[i]);
free (argv);
}
char *
guestfs__canonical_device_name (guestfs_h *g, const char *device)
{
char *ret;
if (STRPREFIX (device, "/dev/hd") ||
STRPREFIX (device, "/dev/vd")) {
ret = safe_strdup (g, device);
ret[5] = 's';
}
else if (STRPREFIX (device, "/dev/mapper/") ||
STRPREFIX (device, "/dev/dm-")) {
/* XXX hide errors */
ret = guestfs_lvm_canonical_lv_name (g, device);
if (ret == NULL)
ret = safe_strdup (g, device);
}
else
ret = safe_strdup (g, device);
return ret; /* caller frees */
}

148
src/private-data.c Normal file
View File

@@ -0,0 +1,148 @@
/* libguestfs
* Copyright (C) 2009-2012 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
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "c-ctype.h"
#include "hash.h"
#include "hash-pjw.h"
#include "guestfs.h"
#include "guestfs-internal.h"
/* Note the private data area is allocated lazily, since the vast
* majority of callers will never use it. This means g->pda is
* likely to be NULL.
*/
struct pda_entry {
char *key; /* key */
void *data; /* opaque user data pointer */
};
static size_t
hasher (void const *x, size_t table_size)
{
struct pda_entry const *p = x;
return hash_pjw (p->key, table_size);
}
static bool
comparator (void const *x, void const *y)
{
struct pda_entry const *a = x;
struct pda_entry const *b = y;
return STREQ (a->key, b->key);
}
static void
freer (void *x)
{
if (x) {
struct pda_entry *p = x;
free (p->key);
free (p);
}
}
void
guestfs_set_private (guestfs_h *g, const char *key, void *data)
{
if (g->pda == NULL) {
g->pda = hash_initialize (16, NULL, hasher, comparator, freer);
if (g->pda == NULL)
g->abort_cb ();
}
struct pda_entry *new_entry = safe_malloc (g, sizeof *new_entry);
new_entry->key = safe_strdup (g, key);
new_entry->data = data;
struct pda_entry *old_entry = hash_delete (g->pda, new_entry);
freer (old_entry);
struct pda_entry *entry = hash_insert (g->pda, new_entry);
if (entry == NULL)
g->abort_cb ();
assert (entry == new_entry);
}
static inline char *
bad_cast (char const *s)
{
return (char *) s;
}
void *
guestfs_get_private (guestfs_h *g, const char *key)
{
if (g->pda == NULL)
return NULL; /* no keys have been set */
const struct pda_entry k = { .key = bad_cast (key) };
struct pda_entry *entry = hash_lookup (g->pda, &k);
if (entry)
return entry->data;
else
return NULL;
}
/* Iterator. */
void *
guestfs_first_private (guestfs_h *g, const char **key_rtn)
{
if (g->pda == NULL)
return NULL;
g->pda_next = hash_get_first (g->pda);
/* Ignore any keys with NULL data pointers. */
while (g->pda_next && g->pda_next->data == NULL)
g->pda_next = hash_get_next (g->pda, g->pda_next);
if (g->pda_next == NULL)
return NULL;
*key_rtn = g->pda_next->key;
return g->pda_next->data;
}
void *
guestfs_next_private (guestfs_h *g, const char **key_rtn)
{
if (g->pda == NULL)
return NULL;
if (g->pda_next == NULL)
return NULL;
/* Walk to the next key with a non-NULL data pointer. */
do {
g->pda_next = hash_get_next (g->pda, g->pda_next);
} while (g->pda_next && g->pda_next->data == NULL);
if (g->pda_next == NULL)
return NULL;
*key_rtn = g->pda_next->key;
return g->pda_next->data;
}

36
src/utils.c Normal file
View File

@@ -0,0 +1,36 @@
/* libguestfs
* Copyright (C) 2009-2012 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
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "guestfs.h"
#include "guestfs-internal.h"
void
guestfs___free_string_list (char **argv)
{
size_t i;
for (i = 0; argv[i] != NULL; ++i)
free (argv[i]);
free (argv);
}