GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/utils/process.cpp Lines: 0 41 0.0 %
Date: 2018-06-18 21:15:20 Branches: 0 38 0.0 %

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