1181254a7Smrg /* Implementation of the HOSTNM intrinsic.
2*b1e83836Smrg Copyright (C) 2005-2022 Free Software Foundation, Inc.
3181254a7Smrg Contributed by François-Xavier Coudert <coudert@clipper.ens.fr>
4181254a7Smrg
5181254a7Smrg This file is part of the GNU Fortran runtime library (libgfortran).
6181254a7Smrg
7181254a7Smrg Libgfortran is free software; you can redistribute it and/or
8181254a7Smrg modify it under the terms of the GNU General Public
9181254a7Smrg License as published by the Free Software Foundation; either
10181254a7Smrg version 3 of the License, or (at your option) any later version.
11181254a7Smrg
12181254a7Smrg Libgfortran is distributed in the hope that it will be useful,
13181254a7Smrg but WITHOUT ANY WARRANTY; without even the implied warranty of
14181254a7Smrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15181254a7Smrg GNU General Public License for more details.
16181254a7Smrg
17181254a7Smrg Under Section 7 of GPL version 3, you are granted additional
18181254a7Smrg permissions described in the GCC Runtime Library Exception, version
19181254a7Smrg 3.1, as published by the Free Software Foundation.
20181254a7Smrg
21181254a7Smrg You should have received a copy of the GNU General Public License and
22181254a7Smrg a copy of the GCC Runtime Library Exception along with this program;
23181254a7Smrg see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24181254a7Smrg <http://www.gnu.org/licenses/>. */
25181254a7Smrg
26181254a7Smrg #include "libgfortran.h"
27181254a7Smrg
28181254a7Smrg #include <errno.h>
29181254a7Smrg #include <string.h>
30181254a7Smrg
31181254a7Smrg #ifdef HAVE_UNISTD_H
32181254a7Smrg #include <unistd.h>
33181254a7Smrg #endif
34181254a7Smrg
35181254a7Smrg #include <limits.h>
36181254a7Smrg
37181254a7Smrg #ifndef HOST_NAME_MAX
38181254a7Smrg #define HOST_NAME_MAX 255
39181254a7Smrg #endif
40181254a7Smrg
41181254a7Smrg
42181254a7Smrg /* Windows32 version */
43181254a7Smrg #if defined __MINGW32__ && !defined HAVE_GETHOSTNAME
44181254a7Smrg #define WIN32_LEAN_AND_MEAN
45181254a7Smrg #include <windows.h>
46181254a7Smrg #include <errno.h>
47181254a7Smrg
48181254a7Smrg static int
w32_gethostname(char * name,size_t len)49181254a7Smrg w32_gethostname (char *name, size_t len)
50181254a7Smrg {
51181254a7Smrg /* We could try the WinSock API gethostname, but that will
52181254a7Smrg fail if WSAStartup function has has not been called. We don't
53181254a7Smrg really need a name that will be understood by socket API, so avoid
54181254a7Smrg unnecessary dependence on WinSock libraries by using
55181254a7Smrg GetComputerName instead. */
56181254a7Smrg
57181254a7Smrg /* On Win9x GetComputerName fails if the input size is less
58181254a7Smrg than MAX_COMPUTERNAME_LENGTH + 1. */
59181254a7Smrg char buffer[MAX_COMPUTERNAME_LENGTH + 1];
60181254a7Smrg DWORD size = sizeof (buffer);
61181254a7Smrg
62181254a7Smrg if (!GetComputerName (buffer, &size))
63181254a7Smrg return -1;
64181254a7Smrg
65181254a7Smrg if ((size = strlen (buffer) + 1) > len)
66181254a7Smrg {
67181254a7Smrg errno = EINVAL;
68181254a7Smrg /* Truncate as per POSIX spec. We do not NUL-terminate. */
69181254a7Smrg size = len;
70181254a7Smrg }
71181254a7Smrg memcpy (name, buffer, (size_t) size);
72181254a7Smrg
73181254a7Smrg return 0;
74181254a7Smrg }
75181254a7Smrg
76181254a7Smrg #undef gethostname
77181254a7Smrg #define gethostname w32_gethostname
78181254a7Smrg #define HAVE_GETHOSTNAME 1
79181254a7Smrg
80181254a7Smrg #endif
81181254a7Smrg
82181254a7Smrg
83181254a7Smrg /* SUBROUTINE HOSTNM(NAME, STATUS)
84181254a7Smrg CHARACTER(len=*), INTENT(OUT) :: NAME
85181254a7Smrg INTEGER, INTENT(OUT), OPTIONAL :: STATUS */
86181254a7Smrg
87181254a7Smrg #ifdef HAVE_GETHOSTNAME
88181254a7Smrg static int
hostnm_0(char * name,gfc_charlen_type name_len)89181254a7Smrg hostnm_0 (char *name, gfc_charlen_type name_len)
90181254a7Smrg {
91181254a7Smrg char p[HOST_NAME_MAX + 1];
92181254a7Smrg int val;
93181254a7Smrg
94181254a7Smrg memset (name, ' ', name_len);
95181254a7Smrg
96181254a7Smrg size_t reqlen = sizeof (p) > (size_t) name_len + 1
97181254a7Smrg ? (size_t) name_len + 1: sizeof (p);
98181254a7Smrg val = gethostname (p, reqlen);
99181254a7Smrg
100181254a7Smrg if (val == 0)
101181254a7Smrg {
102181254a7Smrg for (gfc_charlen_type i = 0; i < name_len && p[i] != '\0'; i++)
103181254a7Smrg name[i] = p[i];
104181254a7Smrg }
105181254a7Smrg
106181254a7Smrg return ((val == 0) ? 0 : errno);
107181254a7Smrg }
108181254a7Smrg
109181254a7Smrg extern void hostnm_i4_sub (char *, GFC_INTEGER_4 *, gfc_charlen_type);
110181254a7Smrg iexport_proto(hostnm_i4_sub);
111181254a7Smrg
112181254a7Smrg void
hostnm_i4_sub(char * name,GFC_INTEGER_4 * status,gfc_charlen_type name_len)113181254a7Smrg hostnm_i4_sub (char *name, GFC_INTEGER_4 *status, gfc_charlen_type name_len)
114181254a7Smrg {
115181254a7Smrg int val = hostnm_0 (name, name_len);
116181254a7Smrg if (status != NULL)
117181254a7Smrg *status = val;
118181254a7Smrg }
119181254a7Smrg iexport(hostnm_i4_sub);
120181254a7Smrg
121181254a7Smrg extern void hostnm_i8_sub (char *, GFC_INTEGER_8 *, gfc_charlen_type);
122181254a7Smrg iexport_proto(hostnm_i8_sub);
123181254a7Smrg
124181254a7Smrg void
hostnm_i8_sub(char * name,GFC_INTEGER_8 * status,gfc_charlen_type name_len)125181254a7Smrg hostnm_i8_sub (char *name, GFC_INTEGER_8 *status, gfc_charlen_type name_len)
126181254a7Smrg {
127181254a7Smrg int val = hostnm_0 (name, name_len);
128181254a7Smrg if (status != NULL)
129181254a7Smrg *status = val;
130181254a7Smrg }
131181254a7Smrg iexport(hostnm_i8_sub);
132181254a7Smrg
133181254a7Smrg extern GFC_INTEGER_4 hostnm (char *, gfc_charlen_type);
134181254a7Smrg export_proto(hostnm);
135181254a7Smrg
136181254a7Smrg GFC_INTEGER_4
hostnm(char * name,gfc_charlen_type name_len)137181254a7Smrg hostnm (char *name, gfc_charlen_type name_len)
138181254a7Smrg {
139181254a7Smrg return hostnm_0 (name, name_len);
140181254a7Smrg }
141181254a7Smrg #endif
142