Tweak last commit.
[gnulib.git] / lib / sethostname.c
1 /* sethostname emulation for glibc compliance.
2
3    Copyright (C) 2011 Free Software Foundation, Inc.
4
5    This program is free software: you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 3 of the License, or
8    (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
17
18 /* Ben Walton <bwalton@artsci.utoronto.ca> */
19
20 #include <config.h>
21
22 /* Unix API.  */
23
24 /* Specification.  */
25 #include <unistd.h>
26
27 #include <errno.h>
28 #include <stdio.h>
29 #include <limits.h>
30
31 /* Set up to LEN chars of NAME as system hostname.
32    Return 0 if ok, set errno and return -1 on error. */
33
34 int
35 sethostname (const char *name, size_t len)
36 {
37   /* Ensure the string isn't too long.  glibc does allow setting an
38      empty hostname so no point in enforcing a lower bound. */
39   if (len > HOST_NAME_MAX)
40     {
41       errno = EINVAL;
42       return -1;
43     }
44
45 #ifdef __minix /* Minix */
46   {
47     FILE *hostf;
48     int r = 0;
49
50     /* glibc returns EFAULT, EINVAL, and EPERM on error.  None of
51        these are appropriate for us to set, even if they may match the
52        situation, during failed open/write/close operations, so we
53        leave errno alone and rely on what the system sets up. */
54     hostf = fopen ("/etc/hostname.file", "w");
55     if (hostf == NULL)
56       r = -1;
57     else
58       {
59         fprintf (hostf, "%.*s\n", (int) len, name);
60         if (ferror (hostf))
61           {
62             /* Close hostf, preserving the errno from the fprintf call.  */
63             int saved_errno = errno;
64             fclose (hostf);
65             errno = saved_errno;
66             r = -1;
67           }
68         else
69           {
70             if (fclose (hostf))
71               /* fclose sets errno on failure.  */
72               r = -1;
73           }
74       }
75
76     return r;
77   }
78 #else
79   /* For platforms that we don't have a better option for, simply bail
80      out.  */
81   errno = ENOSYS;
82   return -1;
83 #endif
84 }