Define sethostname on platforms that do not provide the declaration. Provide a function for platforms that lack it. The general handling of the provided function is to simply return -1 and set errno to ENOSYS. A specific handler is provided for Minix.
Signed-off-by: Ben Walton <bwal...@artsci.utoronto.ca> --- ChangeLog | 8 +++ doc/glibc-functions/sethostname.texi | 16 ++++-- lib/sethostname.c | 87 ++++++++++++++++++++++++++++++++++ m4/sethostname.m4 | 25 ++++++++++ modules/sethostname | 31 ++++++++++++ 5 files changed, 162 insertions(+), 5 deletions(-) create mode 100644 lib/sethostname.c create mode 100644 m4/sethostname.m4 create mode 100644 modules/sethostname diff --git a/ChangeLog b/ChangeLog index eee02b6..c6cf901 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,13 @@ 2011-12-01 Ben Walton <bwal...@artsci.utoronto.ca> + * lib/sethostname.c (sethostname): New file. Provide sethostname + for systems that lack it + * m4/sethostname.m4 (gl_FUNC_SETHOSTNAME): New file. Detection of + sethostname declaration and function. + * modules/sethostname: New file. Define the sethostname module. + +2011-12-01 Ben Walton <bwal...@artsci.utoronto.ca> + * m4/gethostname.m4 (gl_PREREQ_HOST_NAME_MAX): Make this a separate macro so it can be used by the pending sethostname module. diff --git a/doc/glibc-functions/sethostname.texi b/doc/glibc-functions/sethostname.texi index 75cc8ca..ec7b11a 100644 --- a/doc/glibc-functions/sethostname.texi +++ b/doc/glibc-functions/sethostname.texi @@ -2,18 +2,24 @@ @subsection @code{sethostname} @findex sethostname -Gnulib module: --- +Gnulib module: sethostname Portability problems fixed by Gnulib: @itemize -@end itemize - -Portability problems not fixed by Gnulib: -@itemize @item This function is missing on some platforms: Minix 3.1.8, Cygwin, mingw, MSVC 9, Interix 3.5, BeOS. @item This function is not declared on some platforms: AIX 7.1, OSF/1 5.1, Solaris 10. +@item +On Solaris 10, the first argument is @code{char *} instead of +@code{const char *} and the second parameter is @code{int} instead of +@code{size_t}. +@item +On some platforms the Gnulib replacement always fails with ENOSYS. +@end itemize + +Portability problems not fixed by Gnulib: +@itemize @end itemize diff --git a/lib/sethostname.c b/lib/sethostname.c new file mode 100644 index 0000000..e1b7d74 --- /dev/null +++ b/lib/sethostname.c @@ -0,0 +1,87 @@ +/* sethostname emulation for glibc compliance. + + Copyright (C) 2011 Free Software Foundation, 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 3 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, see <http://www.gnu.org/licenses/>. */ + +/* Ben Walton <bwal...@artsci.utoronto.ca> */ + +#include <config.h> + +/* Unix API. */ + +/* Specification. */ +#include <unistd.h> + +#include <errno.h> +#include <stdio.h> +#include <string.h> +#include <limits.h> + +/* Set up to LEN chars of NAME as system hostname. + Return 0 if ok, set errno and return -1 on error. */ + +int +sethostname (const char *name, size_t len) +{ + /* Ensure the string isn't too long. glibc does allow setting an + empty hostname so no point in enforcing a lower bound. */ + if (len > HOST_NAME_MAX) + { + errno = EINVAL; + return -1; + } + + /* NAME does not need to be null terminated so leave room to terminate + regardless of input. */ + char hostname[HOST_NAME_MAX + 1]; + memcpy ((void *) hostname, (const void *) name, len); + hostname[len] = '\0'; + +#ifdef __minix /* Minix */ + { + FILE *hostf; + int r = 0; + + /* glibc returns EFAULT, EINVAL, and EPERM on error. None of + these are appropriate for us to set, even if they may match the + situation, during failed open/write/close operations, so we + leave errno alone and rely on what the system sets up. */ + hostf = fopen ("/etc/hostname.file", "w"); + if (hostf == NULL) + r = -1; + else + { + fprintf (hostf, "%s\n", hostname); + if (ferror (hostf)) + { + clearerr (hostf); + r = -1; + } + + /* use return value of fclose for function return value as it + matches our needs. fclose will also set errno on + failure */ + r = fclose (hostf); + } + + return r; + } +#else + /* For platforms that we don't have a better option for, simply bail + out */ + errno = ENOSYS; + return -1; +#endif +} diff --git a/m4/sethostname.m4 b/m4/sethostname.m4 new file mode 100644 index 0000000..be5b036 --- /dev/null +++ b/m4/sethostname.m4 @@ -0,0 +1,25 @@ +# sethostname.m4 serial 1 +dnl Copyright (C) 2011 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +# Ensure +# - the sethostname() function, +AC_DEFUN([gl_FUNC_SETHOSTNAME], +[ + AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) + + gl_PREREQ_HOST_NAME_MAX + + AC_REPLACE_FUNCS([sethostname]) + AC_CHECK_FUNCS([sethostname]) + if test $ac_cv_func_sethostname = no; then + HAVE_SETHOSTNAME=0 + fi + + AC_CHECK_DECLS([sethostname]) + if test $ac_cv_have_decl_sethostname = no; then + HAVE_DECL_SETHOSTNAME=0 + fi +]) diff --git a/modules/sethostname b/modules/sethostname new file mode 100644 index 0000000..8008756 --- /dev/null +++ b/modules/sethostname @@ -0,0 +1,31 @@ +Description: +sethostname() function: Set machine's hostname. + +Files: +lib/sethostname.c +m4/sethostname.m4 +m4/gethostname.m4 + +Depends-on: +unistd +errno [test $HAVE_SETHOSTNAME = 0] + +configure.ac: +gl_FUNC_SETHOSTNAME +if test $HAVE_SETHOSTNAME = 0; then + AC_LIBOBJ([sethostname]) +fi +gl_UNISTD_MODULE_INDICATOR([sethostname]) + +Makefile.am: + +Include: +<unistd.h> + +Link: + +License: +LGPLv2+ + +Maintainer: +Ben Walton -- 1.7.4.1