xgethostname.c revision 1.2
1/* xgethostname.c -- return current hostname with unlimited length 2 3 Copyright (C) 1992, 1996, 2000, 2001, 2003, 2004, 2005 Free Software 4 Foundation, Inc. 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2, or (at your option) 9 any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; if not, write to the Free Software Foundation, 18 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 19#include <sys/cdefs.h> 20__RCSID("$NetBSD: xgethostname.c,v 1.2 2016/05/17 14:00:09 christos Exp $"); 21 22 23/* written by Jim Meyering */ 24 25#ifdef HAVE_CONFIG_H 26# include <config.h> 27#endif 28 29/* Specification. */ 30#include "xgethostname.h" 31 32#include <stdlib.h> 33#include <errno.h> 34 35#if HAVE_UNISTD_H 36# include <unistd.h> 37#endif 38 39#include "xalloc.h" 40 41#ifndef ENAMETOOLONG 42# define ENAMETOOLONG 0 43#endif 44 45#ifndef INITIAL_HOSTNAME_LENGTH 46# define INITIAL_HOSTNAME_LENGTH 34 47#endif 48 49/* Return the current hostname in malloc'd storage. 50 If malloc fails, exit. 51 Upon any other failure, return NULL and set errno. */ 52char * 53xgethostname (void) 54{ 55 char *hostname = NULL; 56 size_t size = INITIAL_HOSTNAME_LENGTH; 57 58 while (1) 59 { 60 /* Use SIZE_1 here rather than SIZE to work around the bug in 61 SunOS 5.5's gethostname whereby it NUL-terminates HOSTNAME 62 even when the name is as long as the supplied buffer. */ 63 size_t size_1; 64 65 hostname = x2realloc (hostname, &size); 66 size_1 = size - 1; 67 hostname[size_1 - 1] = '\0'; 68 errno = 0; 69 70 if (gethostname (hostname, size_1) == 0) 71 { 72 if (! hostname[size_1 - 1]) 73 break; 74 } 75 else if (errno != 0 && errno != ENAMETOOLONG && errno != EINVAL 76 /* OSX/Darwin does this when the buffer is not large enough */ 77 && errno != ENOMEM) 78 { 79 int saved_errno = errno; 80 free (hostname); 81 errno = saved_errno; 82 return NULL; 83 } 84 } 85 86 return hostname; 87} 88