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