1760c2415Smrg /* Implementation of the GETLOG g77 intrinsic.
2*0bfacb9bSmrg    Copyright (C) 2005-2020 Free Software Foundation, Inc.
3760c2415Smrg    Contributed by François-Xavier Coudert <coudert@clipper.ens.fr>
4760c2415Smrg 
5760c2415Smrg This file is part of the GNU Fortran runtime library (libgfortran).
6760c2415Smrg 
7760c2415Smrg Libgfortran is free software; you can redistribute it and/or
8760c2415Smrg modify it under the terms of the GNU General Public
9760c2415Smrg License as published by the Free Software Foundation; either
10760c2415Smrg version 3 of the License, or (at your option) any later version.
11760c2415Smrg 
12760c2415Smrg Libgfortran is distributed in the hope that it will be useful,
13760c2415Smrg but WITHOUT ANY WARRANTY; without even the implied warranty of
14760c2415Smrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15760c2415Smrg GNU General Public License for more details.
16760c2415Smrg 
17760c2415Smrg Under Section 7 of GPL version 3, you are granted additional
18760c2415Smrg permissions described in the GCC Runtime Library Exception, version
19760c2415Smrg 3.1, as published by the Free Software Foundation.
20760c2415Smrg 
21760c2415Smrg You should have received a copy of the GNU General Public License and
22760c2415Smrg a copy of the GCC Runtime Library Exception along with this program;
23760c2415Smrg see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24760c2415Smrg <http://www.gnu.org/licenses/>.  */
25760c2415Smrg 
26760c2415Smrg #include "libgfortran.h"
27760c2415Smrg 
28760c2415Smrg #include <string.h>
29760c2415Smrg 
30760c2415Smrg #ifdef HAVE_UNISTD_H
31760c2415Smrg #  if defined __MINGW32__ && defined  HAVE_GETLOGIN
32760c2415Smrg #    define _POSIX 1
33760c2415Smrg #  endif
34760c2415Smrg #include <unistd.h>
35760c2415Smrg #endif
36760c2415Smrg #ifdef HAVE_PWD_H
37760c2415Smrg #include <pwd.h>
38760c2415Smrg #endif
39760c2415Smrg 
40760c2415Smrg /* Windows32 version */
41760c2415Smrg #if defined __MINGW32__ && !defined  HAVE_GETLOGIN
42760c2415Smrg #define WIN32_LEAN_AND_MEAN
43760c2415Smrg #include <windows.h>
44760c2415Smrg #include <lmcons.h>  /* for UNLEN */
45760c2415Smrg 
46760c2415Smrg static char *
w32_getlogin(void)47760c2415Smrg w32_getlogin (void)
48760c2415Smrg {
49760c2415Smrg   static char name [UNLEN + 1];
50760c2415Smrg   DWORD namelen = sizeof (name);
51760c2415Smrg 
52760c2415Smrg   GetUserName (name, &namelen);
53760c2415Smrg   return (name[0] == 0 ?  NULL : name);
54760c2415Smrg }
55760c2415Smrg 
56760c2415Smrg #undef getlogin
57760c2415Smrg #define getlogin w32_getlogin
58760c2415Smrg #define HAVE_GETLOGIN 1
59760c2415Smrg 
60760c2415Smrg #endif
61760c2415Smrg 
62760c2415Smrg 
63760c2415Smrg /* GETLOG (LOGIN), g77 intrinsic for retrieving the login name for the
64760c2415Smrg    process.
65760c2415Smrg    CHARACTER(len=*), INTENT(OUT) :: LOGIN  */
66760c2415Smrg 
67760c2415Smrg void PREFIX(getlog) (char *, gfc_charlen_type);
68760c2415Smrg export_proto_np(PREFIX(getlog));
69760c2415Smrg 
70760c2415Smrg void
PREFIX(getlog)71760c2415Smrg PREFIX(getlog) (char * login, gfc_charlen_type login_len)
72760c2415Smrg {
73760c2415Smrg   char *p;
74760c2415Smrg 
75760c2415Smrg   memset (login, ' ', login_len); /* Blank the string.  */
76760c2415Smrg 
77760c2415Smrg #if defined(HAVE_POSIX_GETPWUID_R) && defined(HAVE_GETEUID)
78760c2415Smrg   struct passwd pwd;
79760c2415Smrg   struct passwd *result;
80760c2415Smrg   char *buf;
81760c2415Smrg   int err;
82760c2415Smrg   /* To be pedantic, buflen should be determined by
83760c2415Smrg      sysconf(_SC_GETPW_R_SIZE_MAX), which is 1024 on some tested
84760c2415Smrg      targets; we do something simple in case the target doesn't
85760c2415Smrg      support sysconf.  */
86760c2415Smrg   static const size_t buflen = 1024;
87760c2415Smrg   buf = xmalloc (buflen);
88760c2415Smrg   err = getpwuid_r (geteuid (), &pwd, buf, buflen, &result);
89760c2415Smrg   if (err != 0 || result == NULL)
90760c2415Smrg     goto cleanup;
91760c2415Smrg   p = pwd.pw_name;
92760c2415Smrg #elif defined(HAVE_GETPWUID) && defined(HAVE_GETEUID)
93760c2415Smrg   {
94760c2415Smrg     struct passwd *pw = getpwuid (geteuid ());
95760c2415Smrg     if (pw)
96760c2415Smrg       p = pw->pw_name;
97760c2415Smrg     else
98760c2415Smrg       return;
99760c2415Smrg   }
100760c2415Smrg #elif HAVE_GETLOGIN
101760c2415Smrg   p = getlogin();
102760c2415Smrg # else
103760c2415Smrg   return;
104760c2415Smrg #endif
105760c2415Smrg 
106760c2415Smrg   if (p == NULL)
107760c2415Smrg     goto cleanup;
108760c2415Smrg 
109760c2415Smrg   gfc_charlen_type p_len = strlen (p);
110760c2415Smrg   if (login_len < p_len)
111760c2415Smrg     p_len = login_len;
112760c2415Smrg   memcpy (login, p, p_len);
113760c2415Smrg 
114760c2415Smrg  cleanup:
115760c2415Smrg #if defined (HAVE_POSIX_GETPWUID_R) && defined(HAVE_GETEUID)
116760c2415Smrg   free (buf);
117760c2415Smrg #else
118760c2415Smrg   ;
119760c2415Smrg #endif
120760c2415Smrg }
121