GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/utils/process.cpp Lines: 0 41 0.0 %
Date: 2017-11-29 Branches: 0 38 0.0 %

Line Branch Exec Source
1
/*
2
 *  The ManaPlus Client
3
 *  Copyright (C) 2011-2017  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
#ifndef __native_client__
39
const int timeOut = 10;
40
#endif  // __native_client__
41
42
#ifdef WIN32
43
44
#include "utils/stringutils.h"
45
46
#include <windows.h>
47
48
int execFileWait(const std::string &pathName, const std::string &name A_UNUSED,
49
                 const std::string &arg1, const std::string &arg2,
50
                 const int waitTime A_UNUSED)
51
{
52
//    if (!waitTime)
53
//        waitTime = timeOut;
54
55
    STARTUPINFO siStartupInfo;
56
    PROCESS_INFORMATION piProcessInfo;
57
    memset(&siStartupInfo, 0, sizeof(siStartupInfo));
58
    memset(&piProcessInfo, 0, sizeof(piProcessInfo));
59
    siStartupInfo.cb = sizeof(siStartupInfo);
60
    DWORD ret = -1;
61
    std::string args(std::string(pathName).append(" ").append(arg1));
62
    if (!arg2.empty())
63
        args.append(" ").append(arg2);
64
65
    if (CreateProcess(pathName.c_str(), const_cast<char*>(args.c_str()),
66
        nullptr, nullptr, false, CREATE_DEFAULT_ERROR_MODE, nullptr, nullptr,
67
        &siStartupInfo, &piProcessInfo) != false)
68
    {
69
        if (!WaitForSingleObject(piProcessInfo.hProcess, timeOut * 1000))
70
        {
71
            if (GetExitCodeProcess(piProcessInfo.hProcess, &ret))
72
            {
73
                CloseHandle(piProcessInfo.hProcess);
74
                CloseHandle(piProcessInfo.hThread);
75
                return ret;
76
            }
77
        }
78
        TerminateProcess(piProcessInfo.hProcess, -1);
79
    }
80
81
    CloseHandle(piProcessInfo.hProcess);
82
    CloseHandle(piProcessInfo.hThread);
83
    return -1;
84
}
85
86
bool execFile(const std::string &pathName, const std::string &name A_UNUSED,
87
              const std::string &arg1, const std::string &arg2)
88
{
89
    STARTUPINFO siStartupInfo;
90
    PROCESS_INFORMATION piProcessInfo;
91
    memset(&siStartupInfo, 0, sizeof(siStartupInfo));
92
    memset(&piProcessInfo, 0, sizeof(piProcessInfo));
93
    siStartupInfo.cb = sizeof(siStartupInfo);
94
    std::string args(std::string(pathName).append(" ").append(arg1));
95
    if (!arg2.empty())
96
        args.append(" ").append(arg2);
97
98
    bool res = CreateProcess(pathName.c_str(), const_cast<char*>(
99
        args.c_str()), nullptr, nullptr, false,
100
        CREATE_DEFAULT_ERROR_MODE, nullptr, nullptr, &siStartupInfo,
101
        &piProcessInfo);
102
103
    CloseHandle(piProcessInfo.hProcess);
104
    CloseHandle(piProcessInfo.hThread);
105
    return res;
106
}
107
108
109
#elif defined __linux__ || defined __linux || defined __APPLE__
110
111
#include <sys/types.h>
112
#include <sys/stat.h>
113
#include <sys/wait.h>
114
#include <csignal>
115
116
int execFileWait(const std::string &pathName, const std::string &name,
117
                 const std::string &arg1, const std::string &arg2,
118
                 int waitTime)
119
{
120
    pid_t mon_pid;
121
    int status;
122
123
    if (waitTime == 0)
124
        waitTime = timeOut;
125
126
    if ((mon_pid = fork()) == -1)
127
    {   // fork error
128
        return -1;
129
    }
130
    else if (mon_pid == 0)
131
    {   // monitoring child
132
        pid_t pid;
133
        if ((pid = fork()) == -1)
134
        {   // fork error
135
            return -1;
136
        }
137
        else if (pid == 0)
138
        {   // work child
139
            if (arg2.empty())
140
            {
141
                execl(pathName.c_str(), name.c_str(),
142
                   arg1.c_str(), static_cast<char *>(nullptr));
143
            }
144
            else
145
            {
146
                execl(pathName.c_str(), name.c_str(), arg1.c_str(),
147
                    arg2.c_str(), static_cast<char *>(nullptr));
148
            }
149
            _exit(-1);
150
        }
151
152
        // monitoring process
153
        pid_t sleep_pid;
154
        if ((sleep_pid = fork()) == -1)
155
        {   // fork error
156
            return -1;
157
        }
158
        else if (sleep_pid == 0)
159
        {   // sleep pid
160
            sleep(waitTime);
161
            execl("/bin/true", "/bin/true", static_cast<char *>(nullptr));
162
            _exit(-1);
163
        }
164
165
        // monitoring process
166
        const pid_t exited_pid = wait(&status);
167
        int ret = -1;
168
        if (exited_pid == pid)
169
        {
170
            kill(sleep_pid, SIGKILL);
171
            if (WIFEXITED(status))
172
                ret = WEXITSTATUS(status);
173
        }
174
        else
175
        {
176
            kill(pid, SIGKILL);
177
            ret = -1;
178
        }
179
        wait(nullptr);
180
        execl("/bin/true", "/bin/true", static_cast<char *>(nullptr));
181
        _exit(ret);
182
    }
183
184
    // monitoring parent
185
    waitpid(mon_pid, &status, 0);
186
    if (WIFEXITED(status))
187
        return WEXITSTATUS(status);
188
189
    return -1;
190
}
191
192
bool execFile(const std::string &pathName, const std::string &name,
193
              const std::string &arg1, const std::string &arg2)
194
{
195
    struct stat statbuf;
196
    // file not exists
197
    if (stat(pathName.c_str(), &statbuf) != 0)
198
        return false;
199
200
    pid_t pid;
201
    if ((pid = fork()) == -1)
202
    {   // fork error
203
        return false;
204
    }
205
    else if (pid == 0)
206
    {   // work child
207
        if (arg2.empty())
208
        {
209
            execl(pathName.c_str(), name.c_str(),
210
                arg1.c_str(), static_cast<char *>(nullptr));
211
        }
212
        else
213
        {
214
            execl(pathName.c_str(), name.c_str(), arg1.c_str(),
215
                arg2.c_str(), static_cast<char *>(nullptr));
216
        }
217
        _exit(-1);
218
        PRAGMACLANG6(GCC diagnostic push)
219
        PRAGMACLANG6(GCC diagnostic ignored "-Wunreachable-code-return")
220
        return false;
221
        PRAGMACLANG6(GCC diagnostic pop)
222
    }
223
    return true;
224
}
225
226
#else  // OTHER
227
228
int execFileWait(const std::string &pathName A_UNUSED,
229
                 const std::string &name A_UNUSED,
230
                 const std::string &arg1 A_UNUSED,
231
                 const std::string &arg2 A_UNUSED,
232
                 int waitTime A_UNUSED)
233
{
234
    return -1;
235
}
236
237
bool execFile(const std::string &pathName A_UNUSED,
238
              const std::string &name A_UNUSED,
239
              const std::string &arg1 A_UNUSED,
240
              const std::string &arg2 A_UNUSED)
241
{
242
    return false;
243
}
244
245
#endif  // WIN32
246
247
#if defined WIN64
248
bool openBrowser(std::string url)
249
{
250
    return reinterpret_cast<int64_t>(ShellExecute(nullptr, "open",
251
        replaceAll(url, " ", "").c_str(),
252
        nullptr, nullptr, SW_SHOWNORMAL)) > 32;
253
}
254
#elif defined WIN32
255
bool openBrowser(std::string url)
256
{
257
    return reinterpret_cast<int32_t>(ShellExecute(nullptr, "open",
258
        replaceAll(url, " ", "").c_str(),
259
        nullptr, nullptr, SW_SHOWNORMAL)) > 32;
260
}
261
#elif defined ANDROID
262
#include "utils/stringutils.h"
263
#ifndef USE_SDL2
264
PRAGMA48(GCC diagnostic push)
265
PRAGMA48(GCC diagnostic ignored "-Wshadow")
266
#include <SDL_screenkeyboard.h>
267
PRAGMA48(GCC diagnostic pop)
268
#endif  // USE_SDL2
269
270
bool openBrowser(std::string url)
271
{
272
#ifdef USE_SDL2
273
    SDL_OpenBrowser(replaceAll(url, " ", "").c_str());
274
#else  // USE_SDL2
275
276
    SDL_ANDROID_OpenBrowser(replaceAll(url, " ", "").c_str());
277
#endif  // USE_SDL2
278
279
    return true;
280
}
281
#elif defined __APPLE__
282
bool openBrowser(std::string url)
283
{
284
    return execFile("/usr/bin/open", "/usr/bin/open", url, "");
285
}
286
#elif defined __OpenBSD__ || defined __FreeBSD__ || defined __DragonFly__
287
bool openBrowser(std::string url)
288
{
289
    return execFile("/usr/local/bin/xdg-open",
290
        "/usr/local/bin/xdg-open", url, "");
291
}
292
#elif defined __linux__ || defined __linux
293
bool openBrowser(std::string url)
294
{
295
    return execFile("/usr/bin/xdg-open", "/usr/bin/xdg-open", url, "");
296
}
297
#elif defined __native_client__
298
299
#include "utils/naclmessages.h"
300
301
bool openBrowser(std::string url)
302
{
303
    naclPostMessage("open-browser", url);
304
    return true;
305
}
306
#else  // OTHER
307
bool openBrowser(std::string url)
308
{
309
    return false;
310
}
311
312
#endif  // WIN32
313
314
#ifdef WIN32
315
void setPriority(const bool big)
316
{
317
    HANDLE hCurrentProcess = GetCurrentProcess();
318
    if (big)
319
        SetPriorityClass(hCurrentProcess, ABOVE_NORMAL_PRIORITY_CLASS);
320
    else
321
        SetPriorityClass(hCurrentProcess, BELOW_NORMAL_PRIORITY_CLASS);
322
}
323
#else  // WIN32
324
325
void setPriority(const bool big A_UNUSED)
326
{
327
}
328
#endif  // WIN32