Line data Source code
1 : // Copyright (c) 2025 Made to Order Software Corp. All Rights Reserved
2 : //
3 : // https://snapwebsites.org/project/snapdev
4 : // contact@m2osw.com
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 3 of the License, or
9 : // (at your option) 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, see <https://www.gnu.org/licenses/>.
18 : #pragma once
19 :
20 : /** \file
21 : * \brief Get the current user's name.
22 : *
23 : * There is always a current user on a Unix system. If 0, it is the root
24 : * user. Otherwise, it is at least a UID (user identifier) and the UID
25 : * may be mapped to a user name through the /etc/passwd file.
26 : *
27 : * This function helps in retrieving that name which may or may not
28 : * be in the USER environment variable (i.e. in a CRON environment,
29 : * the USER variable needs to be explicitly set).
30 : */
31 :
32 : // self
33 : //
34 : #include <snapdev/static_to_dynamic_buffer.h>
35 :
36 :
37 : // libexcept
38 : //
39 : //#include "libexcept/exception.h"
40 :
41 :
42 : // C++
43 : //
44 : //#include <algorithm>
45 : #include <string>
46 : //#include <cstdint>
47 : //#include <iomanip>
48 :
49 :
50 : // C
51 : //
52 : #include <pwd.h>
53 : #include <unistd.h>
54 :
55 :
56 :
57 : namespace snapdev
58 : {
59 :
60 :
61 :
62 : /** \brief Retrieve the name of the specified user.
63 : *
64 : * This function retrieve the name of the specified user. If the name cannot
65 : * be gathered, then the function returns an empty string.
66 : *
67 : * This function takes a user identifier and converts it to a user name.
68 : * By default, it uses the getuid() function. If you want to use a different
69 : * UID, make sure to pass the parameter as required.
70 : *
71 : * In effect, by default, the function is equivalent to:
72 : *
73 : * \code
74 : * char const * username(getenv("USER"));
75 : * \endcode
76 : *
77 : * assuming the USER variable is defined properly.
78 : *
79 : * On return, if the user was not found, errno should be set to ENOENT.
80 : * Other errors may occur (interrupt, I/O, permissions, too many files
81 : * opened, not enough memory).
82 : *
83 : * \param[in] uid The user identifier.
84 : *
85 : * \return The name of the user if available, an empty string otherwise.
86 : */
87 6 : inline std::string username(uid_t uid = ::getuid())
88 : {
89 6 : static_to_dynamic_buffer<char> buf;
90 : for(;;)
91 : {
92 6 : struct passwd p;
93 6 : struct passwd * result(nullptr);
94 6 : int const r(getpwuid_r(uid, &p, buf.get(), buf.size(), &result));
95 6 : if(r == 0)
96 : {
97 5 : if(result != nullptr)
98 : {
99 15 : return p.pw_name;
100 : }
101 0 : errno = ENOENT;
102 0 : break;
103 : }
104 1 : if(r != ERANGE)
105 : {
106 1 : if(r == ENOMEM)
107 : {
108 0 : throw std::bad_alloc();
109 : }
110 1 : break;
111 : }
112 : buf.increase_size(1024); // LCOV_EXCL_LINE
113 : } // LCOV_EXCL_LINE
114 :
115 1 : return std::string();
116 6 : }
117 :
118 :
119 :
120 : } // namespace snapdev
121 : // vim: ts=4 sw=4 et
|