From b28f5b3cb2549d311cf973837e6c133d632e6763 Mon Sep 17 00:00:00 2001 From: Dirk Herrmann Date: Wed, 24 Mar 2004 00:49:07 +0000 Subject: [PATCH] * posix.c (scm_gethostname): Make sure len is initialised before it is used. Restructured to (hopefully) represent possible configurations more clearly in the code. Added unwind handler. --- libguile/ChangeLog | 6 ++++ libguile/posix.c | 76 ++++++++++++++++++++++++++++++++-------------- 2 files changed, 60 insertions(+), 22 deletions(-) diff --git a/libguile/ChangeLog b/libguile/ChangeLog index 7693decd3..63e5acb51 100644 --- a/libguile/ChangeLog +++ b/libguile/ChangeLog @@ -1,3 +1,9 @@ +2003-04-24 Dirk Herrmann + + * posix.c (scm_gethostname): Make sure len is initialised before + it is used. Restructured to (hopefully) represent possible + configurations more clearly in the code. Added unwind handler. + 2004-03-23 Kevin Ryde * posix.c (scm_gethostname): Use sysconf(_SC_HOST_NAME_MAX) and/or diff --git a/libguile/posix.c b/libguile/posix.c index cc5cc81fc..6a53599ba 100644 --- a/libguile/posix.c +++ b/libguile/posix.c @@ -28,6 +28,7 @@ #include #include "libguile/_scm.h" +#include "libguile/dynwind.h" #include "libguile/fports.h" #include "libguile/scmsigs.h" #include "libguile/feature.h" @@ -1748,59 +1749,90 @@ SCM_DEFINE (scm_sethostname, "sethostname", 1, 0, 0, #undef FUNC_NAME #endif /* HAVE_SETHOSTNAME */ + #if HAVE_GETHOSTNAME SCM_DEFINE (scm_gethostname, "gethostname", 0, 0, 0, (void), "Return the host name of the current processor.") #define FUNC_NAME s_scm_gethostname { - int len, res, save_errno; - char *p = scm_malloc (len); - SCM name; - - /* Default 256 is for Solaris, under Linux ENAMETOOLONG is returned if not - large enough. SUSv2 specifies 255 maximum too, apparently. */ - len = 256; +#ifdef MAXHOSTNAMELEN /* Various systems define MAXHOSTNAMELEN (including Solaris in fact). - On GNU/Linux this doesn't include the terminating '\0', hence "+ 1". */ -#ifdef MAXHOSTNAMELEN - len = MAXHOSTNAMELEN + 1; -#endif + * On GNU/Linux this doesn't include the terminating '\0', hence "+ 1". */ + const int len = MAXHOSTNAMELEN + 1; + char *const p = scm_malloc (len); + const int res = gethostname (p, len); + + scm_frame_begin (0); + scm_frame_unwind_handler (free, p, 0); + +#else + + /* Default 256 is for Solaris, under Linux ENAMETOOLONG is returned if not + * large enough. SUSv2 specifies 255 maximum too, apparently. */ + int len = 256; + int res; + char *p; + +# if HAVE_SYSCONF && defined (_SC_HOST_NAME_MAX) /* POSIX specifies the HOST_NAME_MAX system parameter for the max size, - which may reflect a particular kernel configuration. - Must watch out for this existing but giving -1, as happens for instance - in gnu/linux glibc 2.3.2. */ -#if HAVE_SYSCONF && defined (_SC_HOST_NAME_MAX) + * which may reflect a particular kernel configuration. + * Must watch out for this existing but giving -1, as happens for instance + * in gnu/linux glibc 2.3.2. */ { - long n = sysconf (_SC_HOST_NAME_MAX); + const long int n = sysconf (_SC_HOST_NAME_MAX); if (n != -1L) len = n; } -#endif + +# endif + + p = scm_malloc (len); + + scm_frame_begin (0); + scm_frame_unwind_handler (free, p, 0); res = gethostname (p, len); while (res == -1 && errno == ENAMETOOLONG) { - p = scm_realloc (p, len * 2); len *= 2; + + /* scm_realloc may throw an exception. */ + p = scm_realloc (p, len); res = gethostname (p, len); } + +#endif + if (res == -1) { - save_errno = errno; + const int save_errno = errno; + + // No guile exceptions can occur before we have freed p's memory. + scm_frame_end (); free (p); + errno = save_errno; SCM_SYSERROR; } - name = scm_makfrom0str (p); - free (p); - return name; + else + { + /* scm_makfrom0str may throw an exception. */ + const SCM name = scm_makfrom0str (p); + + // No guile exceptions can occur before we have freed p's memory. + scm_frame_end (); + free (p); + + return name; + } } #undef FUNC_NAME #endif /* HAVE_GETHOSTNAME */ + void scm_init_posix () {