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
52 bool G::Process::Id::operator==( const Id & rhs ) const noexcept
53{
54 return m_pid == rhs.m_pid ;
55}
56
57 bool G::Process::Id::operator!=( const Id & rhs ) const noexcept
58{
59 return m_pid != rhs.m_pid ;
60}
61
62// ===
63
64 void G::Process::closeFiles( bool /*keep_stderr*/ )
65{
66 std::cout << std::flush ;
67 std::cerr << std::flush ;
68}
69
70 void G::Process::closeOtherFiles( int )
71{
72}
73
74 void G::Process::inheritStandardFiles()
75{
76}
77
78 void G::Process::closeStderr()
79{
80}
81
82 void G::Process::cd( const Path & dir )
83{
84 if( !cd(dir,std::nothrow) )
85 throw CannotChangeDirectory( dir.str() ) ;
86}
87
88 bool G::Process::cd( const Path & dir , std::nothrow_t )
89{
90 return 0 == ::_chdir( dir.cstr() ) ;
91}
92
93 int G::Process::errno_( const SignalSafe & ) noexcept
94{
95 int e = EINVAL ;
96 if( _get_errno( &e ) )
97 e = EINVAL ;
98 return e ;
99}
100
101 void G::Process::errno_( int e ) noexcept
102{
103 _set_errno( e ) ;
104}
105
106 int 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
135 void G::Process::beOrdinary( Identity , bool )
136{
137}
138
139 void G::Process::beOrdinaryForExec( Identity ) noexcept
140{
141}
142
143 void G::Process::beSpecial( Identity , bool )
144{
145}
146
147 void G::Process::beSpecialForExit( SignalSafe , Identity ) noexcept
148{
149}
150
151 void G::Process::setEffectiveUser( Identity )
152{
153}
154
155 void G::Process::setEffectiveGroup( Identity )
156{
157}
158
159 G::Path G::Process::exe()
160{
161 return nowide::exe() ;
162}
163
164 G::Path G::Process::cwd()
165{
166 G::Path result = nowide::cwd() ;
167 if( result.empty() )
168 throw Process::GetCwdError() ;
169 return result ;
170}
171
172 G::Path G::Process::cwd( std::nothrow_t )
173{
174 return nowide::cwd() ;
175}
176
177// ===
178
179 class G::Process::UmaskImp
180{
181} ;
182
183G::Process::Umask::Umask( Process::Umask::Mode )
184{
185}
186
187G::Process::Umask::~Umask()
188= default ;
189
190 void G::Process::Umask::set( Process::Umask::Mode )
191{
192 // not implemented
193}
194
195 void G::Process::Umask::tightenOther()
196{
197 // not implemented
198}
199
200 void G::Process::Umask::loosenGroup()
201{
202 // not implemented
203}
204
G::Identity::invalid
static Identity invalid() noexcept
Returns an invalid identity.
Definition: gidentity_unix.cpp:80
G::Path
A Path object represents a file system path.
Definition: gpath.h:82
G::Path::empty
bool empty() const noexcept
Returns true if the path is empty.
Definition: gpath.h:237
G::Process::beSpecialForExit
static void beSpecialForExit(SignalSafe, Identity special_id) noexcept
A signal-safe version of beSpecial() that should only be used just before process exit.
Definition: gprocess_unix.cpp:162
G::Process::closeOtherFiles
static void closeOtherFiles(int fd_keep=-1)
Closes all open file descriptors except the three standard ones and optionally one other.
Definition: gprocess_unix.cpp:104
G::Process::cwd
static Path cwd()
Returns the current working directory. Throws on error.
Definition: gprocess_unix.cpp:210
G::Process::beOrdinaryAtStartup
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,...
Definition: gprocess_unix.cpp:167
G::Process::beSpecial
static void beSpecial(Identity special_id, bool change_group=true)
Re-acquires special privileges (either root or suid).
Definition: gprocess_unix.cpp:157
G::Process::strerror
static std::string strerror(int errno_)
Translates an 'errno' value into a meaningful diagnostic string.
Definition: gprocess_unix.cpp:142
G::Process::beOrdinaryForExec
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.
Definition: gprocess_unix.cpp:191
G::Process::exe
static Path exe()
Returns the absolute path of the current executable, independent of the argv array passed to main().
Definition: gprocess_unix.cpp:265
G::Process::setEffectiveGroup
static void setEffectiveGroup(Identity)
Sets the effective group-id. Throws on error.
Definition: gprocess_unix.cpp:204
G::Process::closeStderr
static void closeStderr()
Closes stderr and reopens it to the null device.
Definition: gprocess_unix.cpp:85
G::Process::inheritStandardFiles
static void inheritStandardFiles()
Makes sure that the standard file descriptors are inherited.
Definition: gprocess_unix.cpp:118
G::Process::beOrdinary
static void beOrdinary(Identity ordinary_id, bool change_group)
Releases special privileges.
Definition: gprocess_unix.cpp:186
G::Process::errno_
static int errno_(const SignalSafe &=G::SignalSafe()) noexcept
Returns the process's current 'errno' value.
Definition: gprocess_unix.cpp:125
G::Process::setEffectiveUser
static void setEffectiveUser(Identity)
Sets the effective user-id. Throws on error.
Definition: gprocess_unix.cpp:197
G::Process::closeFiles
static void closeFiles(bool keep_stderr=false)
Closes all open file descriptors and reopens stdin, stdout and possibly stderr to the null device.
Definition: gprocess_unix.cpp:90
G::Process::cd
static void cd(const Path &dir)
Changes directory.
Definition: gprocess_unix.cpp:74
G::Process::errorMessage
static std::string errorMessage(DWORD error)
Translates a GetLastError() value into a meaningful diagnostic string.
Definition: gprocess_unix.cpp:151
G::Str::trimRight
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
G::Str::lower
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
G::Str::isPrintableAscii
static bool isPrintableAscii(std::string_view s) noexcept
Returns true if every character is between 0x20 and 0x7e inclusive.
Definition: gstr.cpp:413
gconvert.h
gexception.h
glog.h
gnowide.h
Contains inline functions that convert to and from UTF-8 strings in order to call wide-character "W()...
gprocess.h
gstr.h