Split lines with many copyright years
[alexxy/gromacs.git] / src / gromacs / utility / sysinfo.cpp
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2014,2015,2016,2017,2018 by the GROMACS development team.
5  * Copyright (c) 2019,2020, by the GROMACS development team, led by
6  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
7  * and including many others, as listed in the AUTHORS file in the
8  * top-level source directory and at http://www.gromacs.org.
9  *
10  * GROMACS is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public License
12  * as published by the Free Software Foundation; either version 2.1
13  * of the License, or (at your option) any later version.
14  *
15  * GROMACS is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with GROMACS; if not, see
22  * http://www.gnu.org/licenses, or write to the Free Software Foundation,
23  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
24  *
25  * If you want to redistribute modifications to GROMACS, please
26  * consider that scientific software is very special. Version
27  * control is crucial - bugs must be traceable. We will be happy to
28  * consider code for inclusion in the official distribution, but
29  * derived work must not be called official GROMACS. Details are found
30  * in the README & COPYING files - if they are missing, get the
31  * official version at http://www.gromacs.org.
32  *
33  * To help us fund GROMACS development, we humbly ask that you cite
34  * the research papers on the package. Check out http://www.gromacs.org.
35  */
36 /*! \internal \file
37  * \brief
38  * Implements functions from sysinfo.h.
39  *
40  * \author Teemu Murtola <teemu.murtola@gmail.com>
41  * \ingroup module_utility
42  */
43 #include "gmxpre.h"
44
45 #include "sysinfo.h"
46
47 #include "config.h"
48
49 #include <cstring>
50 #include <ctime>
51
52 #include <array>
53
54 #include <sys/types.h>
55 #ifdef HAVE_SYS_TIME_H
56 #    include <sys/time.h>
57 #endif
58 #if GMX_NATIVE_WINDOWS
59 #    include <Windows.h>
60 #    include <process.h>
61 #endif
62 #if HAVE_PWD_H
63 #    include <pwd.h>
64 #endif
65 #ifdef HAVE_UNISTD_H
66 #    include <unistd.h>
67 #endif
68
69 #include "gromacs/utility/basedefinitions.h"
70 #include "gromacs/utility/gmxassert.h"
71
72 namespace
73 {
74 //! Static return value for cases when a string value is not available.
75 const char c_unknown[] = "unknown";
76 } // namespace
77
78 int gmx_gethostname(char* buf, size_t len)
79 {
80     GMX_RELEASE_ASSERT(len >= 8, "Input buffer is too short");
81 #if GMX_NATIVE_WINDOWS
82     DWORD dlen = len;
83     if (GetComputerName(buf, &dlen))
84     {
85         return 0;
86     }
87 #elif defined(HAVE_UNISTD_H) && !defined(__native_client__)
88     if (gethostname(buf, len - 1) == 0)
89     {
90         buf[len - 1] = '\0';
91         return 0;
92     }
93 #endif
94     strcpy(buf, c_unknown);
95     return -1;
96 }
97
98 int gmx_getpid()
99 {
100 #if GMX_NATIVE_WINDOWS
101     return _getpid();
102 #else
103     return getpid();
104 #endif
105 }
106
107 int gmx_getuid()
108 {
109 #if defined(HAVE_UNISTD_H) && !defined(__MINGW32__)
110     return getuid();
111 #else
112     return -1;
113 #endif
114 }
115
116 int gmx_getusername(char* buf, size_t len)
117 {
118     GMX_RELEASE_ASSERT(len >= 8, "Input buffer is too short");
119     // TODO: nice_header() used getpwuid() instead; consider using getpwuid_r()
120     // here.  If not, get rid of HAVE_PWD_H completely.
121 #if GMX_NATIVE_WINDOWS
122     DWORD dlen = len;
123     if (GetUserName(buf, &dlen))
124     {
125         return 0;
126     }
127 #elif defined(HAVE_UNISTD_H) && !__has_feature(memory_sanitizer) // MSAN Issue 83
128     if (!getlogin_r(buf, len))
129     {
130         buf[len - 1] = '\0';
131         return 0;
132     }
133 #endif
134     strcpy(buf, c_unknown);
135     return -1;
136 }
137
138 std::string gmx_ctime_r(const time_t* clock)
139 {
140 #ifdef _MSC_VER
141     std::array<char, 1024> buf;
142     ctime_s(buf.data(), buf.size(), clock);
143     return std::string(buf.begin(), buf.end());
144 #elif GMX_NATIVE_WINDOWS
145     char* tmpbuf = ctime(clock);
146     return tmpbuf;
147 #elif (defined(__sun))
148     /*Solaris*/
149     std::array<char, 1024> buf;
150     ctime_r(clock, buf.data());
151     return std::string(buf.begin(), buf.end());
152 #else
153     std::array<char, 1024> buf;
154     ctime_r(clock, buf.data());
155     return std::string(buf.begin(), buf.end());
156 #endif
157 }
158
159 std::string gmx_format_current_time()
160 {
161     time_t clock = time(nullptr);
162     return gmx_ctime_r(&clock);
163 }
164
165 int gmx_set_nice(int level)
166 {
167 #if GMX_USE_NICE
168     // TODO: This may not be reliable, but currently the return value is not
169     // used.
170     if (nice(level) != -1)
171     {
172         return 0;
173     }
174 #else
175     GMX_UNUSED_VALUE(level);
176 #endif
177     return -1;
178 }