E-MailRelay
gprocess_win32.cpp
Go to the documentation of this file.
1//
2// Copyright (C) 2001-2024 Graeme Walker <graeme_walker@users.sourceforge.net>
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see <http://www.gnu.org/licenses/>.
16// ===
17///
18/// \file gprocess_win32.cpp
19///
20
21#include "gdef.h"
22#include "gnowide.h"
23#include "gprocess.h"
24#include "gexception.h"
25#include "gconvert.h"
26#include "gstr.h"
27#include "glog.h"
28#include <iostream>
29#include <fstream>
30#include <sstream>
31#include <algorithm>
32#include <vector>
33#include <sys/types.h>
34#include <sys/stat.h>
35#include <process.h>
36#include <io.h>
37#include <fcntl.h>
38#include <direct.h> // _getcwd()
39
40G::Process::Id::Id() noexcept
41{
42 m_pid = static_cast<unsigned int>(::_getpid()) ; // or ::GetCurrentProcessId()
43}
44
45std::string G::Process::Id::str() const
46{
47 std::ostringstream ss ;
48 ss << m_pid ;
49 return ss.str() ;
50}
51
52bool G::Process::Id::operator==( const Id & rhs ) const noexcept
53{
54 return m_pid == rhs.m_pid ;
55}
56
57bool G::Process::Id::operator!=( const Id & rhs ) const noexcept
58{
59 return m_pid != rhs.m_pid ;
60}
61
62// ===
63
64void G::Process::closeFiles( bool /*keep_stderr*/ )
65{
66 std::cout << std::flush ;
67 std::cerr << std::flush ;
68}
69
71{
72}
73
75{
76}
77
79{
80}
81
82void G::Process::cd( const Path & dir )
83{
84 if( !cd(dir,std::nothrow) )
85 throw CannotChangeDirectory( dir.str() ) ;
86}
87
88bool G::Process::cd( const Path & dir , std::nothrow_t )
89{
90 return 0 == ::_chdir( dir.cstr() ) ;
91}
92
93int G::Process::errno_( const SignalSafe & ) noexcept
94{
95 int e = EINVAL ;
96 if( _get_errno( &e ) )
97 e = EINVAL ;
98 return e ;
99}
100
101void G::Process::errno_( int e ) noexcept
102{
103 _set_errno( e ) ;
104}
105
106int G::Process::errno_( const SignalSafe & , int e ) noexcept
107{
108 int old = errno_( SignalSafe() ) ;
109 _set_errno( e ) ;
110 return old ;
111}
112
113std::string G::Process::strerror( int errno_ )
114{
115 std::string s = nowide::strerror( errno_ ) ;
116 return Str::isPrintableAscii(s) ? Str::lower(s) : s ;
117}
118
119std::string G::Process::errorMessage( DWORD e )
120{
121 std::string s = nowide::formatMessage( e ) ;
122 G::Str::trimRight( s , ".\r\n" ) ;
123 if( s.empty() )
124 return std::string("error ").append( std::to_string(e) ) ;
125 else
126 return Str::isPrintableAscii(s) ? Str::lower(s) : s ;
127}
128
129std::pair<G::Identity,G::Identity> G::Process::beOrdinaryAtStartup( const std::string & , bool )
130{
131 // identity switching not implemented for windows
132 return { Identity::invalid() , Identity::invalid() } ;
133}
134
135void G::Process::beOrdinary( Identity , bool )
136{
137}
138
139void G::Process::beOrdinaryForExec( Identity ) noexcept
140{
141}
142
143void G::Process::beSpecial( Identity , bool )
144{
145}
146
147void G::Process::beSpecialForExit( SignalSafe , Identity ) noexcept
148{
149}
150
151void G::Process::setEffectiveUser( Identity )
152{
153}
154
155void G::Process::setEffectiveGroup( Identity )
156{
157}
158
160{
161 return nowide::exe() ;
162}
163
165{
166 G::Path result = nowide::cwd() ;
167 if( result.empty() )
168 throw Process::GetCwdError() ;
169 return result ;
170}
171
172G::Path G::Process::cwd( std::nothrow_t )
173{
174 return nowide::cwd() ;
175}
176
177// ===
178
179class G::Process::UmaskImp
180{
181} ;
182
183G::Process::Umask::Umask( Process::Umask::Mode )
184{
185}
186
187G::Process::Umask::~Umask()
188= default ;
189
190void G::Process::Umask::set( Process::Umask::Mode )
191{
192 // not implemented
193}
194
195void G::Process::Umask::tightenOther()
196{
197 // not implemented
198}
199
200void G::Process::Umask::loosenGroup()
201{
202 // not implemented
203}
204
static Identity invalid() noexcept
Returns an invalid identity.
A Path object represents a file system path.
Definition: gpath.h:82
bool empty() const noexcept
Returns true if the path is empty.
Definition: gpath.h:237
static void beSpecialForExit(SignalSafe, Identity special_id) noexcept
A signal-safe version of beSpecial() that should only be used just before process exit.
static void closeOtherFiles(int fd_keep=-1)
Closes all open file descriptors except the three standard ones and optionally one other.
static Path cwd()
Returns the current working directory. Throws on error.
static std::pair< Identity, Identity > beOrdinaryAtStartup(const std::string &nobody, bool change_group)
Revokes special privileges (root or suid) at startup, possibly including extra group membership,...
static void beSpecial(Identity special_id, bool change_group=true)
Re-acquires special privileges (either root or suid).
static std::string strerror(int errno_)
Translates an 'errno' value into a meaningful diagnostic string.
static void beOrdinaryForExec(Identity run_as_id) noexcept
Sets the real and effective user-id and group-ids to those given, on a best-effort basis.
static Path exe()
Returns the absolute path of the current executable, independent of the argv array passed to main().
static void setEffectiveGroup(Identity)
Sets the effective group-id. Throws on error.
static void closeStderr()
Closes stderr and reopens it to the null device.
static void inheritStandardFiles()
Makes sure that the standard file descriptors are inherited.
static void beOrdinary(Identity ordinary_id, bool change_group)
Releases special privileges.
static int errno_(const SignalSafe &=G::SignalSafe()) noexcept
Returns the process's current 'errno' value.
static void setEffectiveUser(Identity)
Sets the effective user-id. Throws on error.
static void closeFiles(bool keep_stderr=false)
Closes all open file descriptors and reopens stdin, stdout and possibly stderr to the null device.
static void cd(const Path &dir)
Changes directory.
static std::string errorMessage(DWORD error)
Translates a GetLastError() value into a meaningful diagnostic string.
static std::string & trimRight(std::string &s, std::string_view ws, std::size_t limit=0U)
Trims the rhs of s, taking off up to 'limit' of the 'ws' characters.
Definition: gstr.cpp:313
static std::string lower(std::string_view)
Returns a copy of 's' in which all seven-bit upper-case characters have been replaced by lower-case c...
Definition: gstr.cpp:824
static bool isPrintableAscii(std::string_view s) noexcept
Returns true if every character is between 0x20 and 0x7e inclusive.
Definition: gstr.cpp:413
Contains inline functions that convert to and from UTF-8 strings in order to call wide-character "W()...