GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/utils/process.cpp Lines: 0 45 0.0 %
Date: 2021-03-17 Branches: 0 36 0.0 %

Line Branch Exec Source
1
/*
2
 *  The ManaPlus Client
3
 *  Copyright (C) 2011-2019  The ManaPlus Developers
4
 *  Copyright (C) 2019-2021  Andrei Karas
5
 *
6
 *  This file is part of The ManaPlus Client.
7
 *
8
 *  This program is free software; you can redistribute it and/or modify
9
 *  it under the terms of the GNU General Public License as published by
10
 *  the Free Software Foundation; either version 2 of the License, or
11
 *  any later version.
12
 *
13
 *  This program is distributed in the hope that it will be useful,
14
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 *  GNU General Public License for more details.
17
 *
18
 *  You should have received a copy of the GNU General Public License
19
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
 */
21
22
#include "utils/process.h"
23
24
#include <unistd.h>
25
26
#include "localconsts.h"
27
28
PRAGMA48(GCC diagnostic push)
29
PRAGMA48(GCC diagnostic ignored "-Wshadow")
30
#ifdef USE_SDL2
31
#ifdef ANDROID
32
#include <SDL_system.h>
33
#endif  // ANDROID
34
#endif  // USE_SDL2
35
PRAGMA48(GCC diagnostic pop)
36
37
#include "debug.h"
38
39
#if defined(WIN32) || defined(__linux__) || \
40
    defined(__linux) || defined(__APPLE__)
41
const int timeOut = 10;
42
#endif  // defined(WIN32) || defined(__linux__) ||
43
        // defined(__linux) || defined(__APPLE__)
44
45
#ifdef WIN32
46
47
#include "utils/stringutils.h"
48
49
#include <windows.h>
50
51
int execFileWait(const std::string &pathName, const std::string &name A_UNUSED,
52
                 const std::string &arg1, const std::string &arg2,
53
                 const int waitTime A_UNUSED)
54
{
55
//    if (!waitTime)
56
//        waitTime = timeOut;
57
58
    STARTUPINFO siStartupInfo;
59
    PROCESS_INFORMATION piProcessInfo;
60
    memset(&siStartupInfo, 0, sizeof(siStartupInfo));
61
    memset(&piProcessInfo, 0, sizeof(piProcessInfo));
62
    siStartupInfo.cb = sizeof(siStartupInfo);
63
    DWORD ret = -1;
64
    std::string args(std::string(pathName).append(" ").append(arg1));
65
    if (!arg2.empty())
66
        args.append(" ").append(arg2);
67
68
    if (CreateProcess(pathName.c_str(), const_cast<char*>(args.c_str()),
69
        nullptr, nullptr, false, CREATE_DEFAULT_ERROR_MODE, nullptr, nullptr,
70
        &siStartupInfo, &piProcessInfo) != false)
71
    {
72
        if (!WaitForSingleObject(piProcessInfo.hProcess, timeOut * 1000))
73
        {
74
            if (GetExitCodeProcess(piProcessInfo.hProcess, &ret))
75
            {
76
                CloseHandle(piProcessInfo.hProcess);
77
                CloseHandle(piProcessInfo.hThread);
78
                return ret;
79
            }
80
        }
81
        TerminateProcess(piProcessInfo.hProcess, -1);
82
    }
83
84
    CloseHandle(piProcessInfo.hProcess);
85
    CloseHandle(piProcessInfo.hThread);
86
    return -1;
87
}
88
89
bool execFile(const std::string &pathName, const std::string &name A_UNUSED,
90
              const std::string &arg1, const std::string &arg2)
91
{
92
    STARTUPINFO siStartupInfo;
93
    PROCESS_INFORMATION piProcessInfo;
94
    memset(&siStartupInfo, 0, sizeof(siStartupInfo));
95
    memset(&piProcessInfo, 0, sizeof(piProcessInfo));
96
    siStartupInfo.cb = sizeof(siStartupInfo);
97
    std::string args(std::string(pathName).append(" ").append(arg1));
98
    if (!arg2.empty())
99
        args.append(" ").append(arg2);
100
101
    bool res = CreateProcess(pathName.c_str(), const_cast<char*>(
102
        args.c_str()), nullptr, nullptr, false,
103
        CREATE_DEFAULT_ERROR_MODE, nullptr, nullptr, &siStartupInfo,
104
        &piProcessInfo);
105
106
    CloseHandle(piProcessInfo.hProcess);
107
    CloseHandle(piProcessInfo.hThread);
108
    return res;
109
}
110
111
112
#elif defined __linux__ || defined __linux || defined __APPLE__
113
114
#include <sys/types.h>
115
#include <sys/stat.h>
116
#include <sys/wait.h>
117
#include <csignal>
118
119
int execFileWait(const std::string &pathName, const std::string &name,
120
                 const std::string &arg1, const std::string &arg2,
121
                 int waitTime)
122
{
123
    pid_t mon_pid;
124
    int status;
125
126
    if (waitTime == 0)
127
        waitTime = timeOut;
128
129
    if ((mon_pid = fork()) == -1)
130
    {   // fork error
131
        return -1;
132
    }
133
    else if (mon_pid == 0)
134
    {   // monitoring child
135
        pid_t pid;
136
        if ((pid = fork()) == -1)
137
        {   // fork error
138
            return -1;
139
        }
140
        else if (pid == 0)
141
        {   // work child
142
            if (arg2.empty())
143
            {
144
                execl(pathName.c_str(), name.c_str(),
145
                   arg1.c_str(), static_cast<char *>(nullptr));
146
            }
147
            else
148
            {
149
                execl(pathName.c_str(), name.c_str(), arg1.c_str(),
150
                    arg2.c_str(), static_cast<char *>(nullptr));
151
            }
152
            _exit(-1);
153
        }
154
155
        // monitoring process
156
        pid_t sleep_pid;
157
        if ((sleep_pid = fork()) == -1)
158
        {   // fork error
159
            return -1;
160
        }
161
        else if (sleep_pid == 0)
162
        {   // sleep pid
163
            sleep(waitTime);
164
            execl("/bin/true", "/bin/true", static_cast<char *>(nullptr));
165
            _exit(-1);
166
        }
167
168
        // monitoring process
169
        const pid_t exited_pid = wait(&status);
170
        int ret = -1;
171
        if (exited_pid == pid)
172
        {
173
            kill(sleep_pid, SIGKILL);
174
            if (WIFEXITED(status))
175
                ret = WEXITSTATUS(status);
176
        }
177
        else
178
        {
179
            kill(pid, SIGKILL);
180
            ret = -1;
181
        }
182
        wait(nullptr);
183
        execl("/bin/true", "/bin/true", static_cast<char *>(nullptr));
184
        _exit(ret);
185
    }
186
187
    // monitoring parent
188
    waitpid(mon_pid, &status, 0);
189
    if (WIFEXITED(status))
190
        return WEXITSTATUS(status);
191
192
    return -1;
193
}
194
195
bool execFile(const std::string &pathName, const std::string &name,
196
              const std::string &arg1, const std::string &arg2)
197
{
198
    struct stat statbuf;
199
    // file not exists
200
    if (stat(pathName.c_str(), &statbuf) != 0)
201
        return false;
202
203
    pid_t pid;
204
    if ((pid = fork()) == -1)
205
    {   // fork error
206
        return false;
207
    }
208
    else if (pid == 0)
209
    {   // work child
210
        if (arg2.empty())
211
        {
212
            execl(pathName.c_str(), name.c_str(),
213
                arg1.c_str(), static_cast<char *>(nullptr));
214
        }
215
        else
216
        {
217
            execl(pathName.c_str(), name.c_str(), arg1.c_str(),
218
                arg2.c_str(), static_cast<char *>(nullptr));
219
        }
220
        _exit(-1);
221
        PRAGMACLANG6(GCC diagnostic push)
222
        PRAGMACLANG6(GCC diagnostic ignored "-Wunreachable-code-return")
223
        return false;
224
        PRAGMACLANG6(GCC diagnostic pop)
225
    }
226
    return true;
227
}
228
229
#else  // OTHER
230
231
int execFileWait(const std::string &pathName A_UNUSED,
232
                 const std::string &name A_UNUSED,
233
                 const std::string &arg1 A_UNUSED,
234
                 const std::string &arg2 A_UNUSED,
235
                 int waitTime A_UNUSED)
236
{
237
    return -1;
238
}
239
240
bool execFile(const std::string &pathName A_UNUSED,
241
              const std::string &name A_UNUSED,
242
              const std::string &arg1 A_UNUSED,
243
              const std::string &arg2 A_UNUSED)
244
{
245
    return false;
246
}
247
248
#endif  // WIN32
249
250
#if defined WIN64
251
bool openBrowser(std::string url)
252
{
253
    return reinterpret_cast<int64_t>(ShellExecute(nullptr, "open",
254
        replaceAll(url, " ", "").c_str(),
255
        nullptr, nullptr, SW_SHOWNORMAL)) > 32;
256
}
257
#elif defined WIN32
258
bool openBrowser(std::string url)
259
{
260
    return reinterpret_cast<int32_t>(ShellExecute(nullptr, "open",
261
        replaceAll(url, " ", "").c_str(),
262
        nullptr, nullptr, SW_SHOWNORMAL)) > 32;
263
}
264
#elif defined ANDROID
265
#include "utils/stringutils.h"
266
#ifndef USE_SDL2
267
PRAGMA48(GCC diagnostic push)
268
PRAGMA48(GCC diagnostic ignored "-Wshadow")
269
#include <SDL_screenkeyboard.h>
270
PRAGMA48(GCC diagnostic pop)
271
#endif  // USE_SDL2
272
273
bool openBrowser(std::string url)
274
{
275
#ifdef USE_SDL2
276
    SDL_OpenBrowser(replaceAll(url, " ", "").c_str());
277
#else  // USE_SDL2
278
279
    SDL_ANDROID_OpenBrowser(replaceAll(url, " ", "").c_str());
280
#endif  // USE_SDL2
281
282
    return true;
283
}
284
#elif defined __APPLE__
285
bool openBrowser(std::string url)
286
{
287
    return execFile("/usr/bin/open", "/usr/bin/open", url, "");
288
}
289
#elif defined __OpenBSD__ || defined __FreeBSD__ || defined __DragonFly__
290
bool openBrowser(std::string url)
291
{
292
    return execFile("/usr/local/bin/xdg-open",
293
        "/usr/local/bin/xdg-open", url, "");
294
}
295
#elif defined __linux__ || defined __linux
296
bool openBrowser(std::string url)
297
{
298
    return execFile("/usr/bin/xdg-open", "/usr/bin/xdg-open", url, "");
299
}
300
#elif defined __native_client__
301
302
#include "utils/naclmessages.h"
303
304
bool openBrowser(std::string url)
305
{
306
    naclPostMessage("open-browser", url);
307
    return true;
308
}
309
#else  // OTHER
310
bool openBrowser(std::string url A_UNUSED)
311
{
312
    return false;
313
}
314
315
#endif  // WIN32
316
317
#ifdef WIN32
318
void setPriority(const bool big)
319
{
320
    HANDLE hCurrentProcess = GetCurrentProcess();
321
    if (big)
322
        SetPriorityClass(hCurrentProcess, ABOVE_NORMAL_PRIORITY_CLASS);
323
    else
324
        SetPriorityClass(hCurrentProcess, BELOW_NORMAL_PRIORITY_CLASS);
325
}
326
#else  // WIN32
327
328
void setPriority(const bool big A_UNUSED)
329
{
330
}
331
#endif  // WIN32