Coverage Report

Created: 2025-07-01 06:46

/src/FreeRDP/winpr/libwinpr/thread/process.c
Line
Count
Source (jump to first uncovered line)
1
/**
2
 * WinPR: Windows Portable Runtime
3
 * Process Thread Functions
4
 *
5
 * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6
 * Copyright 2014 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
7
 *
8
 * Licensed under the Apache License, Version 2.0 (the "License");
9
 * you may not use this file except in compliance with the License.
10
 * You may obtain a copy of the License at
11
 *
12
 *     http://www.apache.org/licenses/LICENSE-2.0
13
 *
14
 * Unless required by applicable law or agreed to in writing, software
15
 * distributed under the License is distributed on an "AS IS" BASIS,
16
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
 * See the License for the specific language governing permissions and
18
 * limitations under the License.
19
 */
20
21
#include <winpr/config.h>
22
23
#include <winpr/handle.h>
24
#include "../handle/nonehandle.h"
25
26
#include <winpr/thread.h>
27
#include <winpr/wlog.h>
28
29
/**
30
 * CreateProcessA
31
 * CreateProcessW
32
 * CreateProcessAsUserA
33
 * CreateProcessAsUserW
34
 * ExitProcess
35
 * GetCurrentProcess
36
 * GetCurrentProcessId
37
 * GetExitCodeProcess
38
 * GetProcessHandleCount
39
 * GetProcessId
40
 * GetProcessIdOfThread
41
 * GetProcessMitigationPolicy
42
 * GetProcessTimes
43
 * GetProcessVersion
44
 * OpenProcess
45
 * OpenProcessToken
46
 * ProcessIdToSessionId
47
 * SetProcessAffinityUpdateMode
48
 * SetProcessMitigationPolicy
49
 * SetProcessShutdownParameters
50
 * TerminateProcess
51
 */
52
53
#ifndef _WIN32
54
55
#include <winpr/assert.h>
56
#include <winpr/crt.h>
57
#include <winpr/path.h>
58
#include <winpr/environment.h>
59
60
#include <grp.h>
61
62
#include <signal.h>
63
#include <sys/types.h>
64
#include <sys/wait.h>
65
66
#ifdef __linux__
67
#include <sys/syscall.h>
68
#include <fcntl.h>
69
#include <errno.h>
70
#endif /* __linux__ */
71
72
#include "thread.h"
73
74
#include "../security/security.h"
75
76
#ifndef NSIG
77
#ifdef SIGMAX
78
#define NSIG SIGMAX
79
#else
80
#define NSIG 64
81
#endif
82
#endif
83
84
/**
85
 * If the file name does not contain a directory path, the system searches for the executable file
86
 * in the following sequence:
87
 *
88
 * 1) The directory from which the application loaded.
89
 * 2) The current directory for the parent process.
90
 * 3) The 32-bit Windows system directory. Use the GetSystemDirectory function to get the path of
91
 * this directory. 4) The 16-bit Windows system directory. There is no function that obtains the
92
 * path of this directory, but it is searched. The name of this directory is System. 5) The Windows
93
 * directory. Use the GetWindowsDirectory function to get the path of this directory. 6) The
94
 * directories that are listed in the PATH environment variable. Note that this function does not
95
 * search the per-application path specified by the App Paths registry key. To include this
96
 * per-application path in the search sequence, use the ShellExecute function.
97
 */
98
99
static char* FindApplicationPath(char* application)
100
0
{
101
0
  LPCSTR pathName = "PATH";
102
0
  char* path = NULL;
103
0
  char* save = NULL;
104
0
  DWORD nSize = 0;
105
0
  LPSTR lpSystemPath = NULL;
106
0
  char* filename = NULL;
107
108
0
  if (!application)
109
0
    return NULL;
110
111
0
  if (application[0] == '/')
112
0
    return _strdup(application);
113
114
0
  nSize = GetEnvironmentVariableA(pathName, NULL, 0);
115
116
0
  if (!nSize)
117
0
    return _strdup(application);
118
119
0
  lpSystemPath = (LPSTR)malloc(nSize);
120
121
0
  if (!lpSystemPath)
122
0
    return NULL;
123
124
0
  if (GetEnvironmentVariableA(pathName, lpSystemPath, nSize) != nSize - 1)
125
0
  {
126
0
    free(lpSystemPath);
127
0
    return NULL;
128
0
  }
129
130
0
  save = NULL;
131
0
  path = strtok_s(lpSystemPath, ":", &save);
132
133
0
  while (path)
134
0
  {
135
0
    filename = GetCombinedPath(path, application);
136
137
0
    if (winpr_PathFileExists(filename))
138
0
    {
139
0
      break;
140
0
    }
141
142
0
    free(filename);
143
0
    filename = NULL;
144
0
    path = strtok_s(NULL, ":", &save);
145
0
  }
146
147
0
  free(lpSystemPath);
148
0
  return filename;
149
0
}
150
151
static HANDLE CreateProcessHandle(pid_t pid);
152
static BOOL ProcessHandleCloseHandle(HANDLE handle);
153
154
static BOOL CreateProcessExA(HANDLE hToken, WINPR_ATTR_UNUSED DWORD dwLogonFlags,
155
                             LPCSTR lpApplicationName, WINPR_ATTR_UNUSED LPSTR lpCommandLine,
156
                             WINPR_ATTR_UNUSED LPSECURITY_ATTRIBUTES lpProcessAttributes,
157
                             WINPR_ATTR_UNUSED LPSECURITY_ATTRIBUTES lpThreadAttributes,
158
                             WINPR_ATTR_UNUSED BOOL bInheritHandles,
159
                             WINPR_ATTR_UNUSED DWORD dwCreationFlags, LPVOID lpEnvironment,
160
                             LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo,
161
                             LPPROCESS_INFORMATION lpProcessInformation)
162
0
{
163
0
  pid_t pid = 0;
164
0
  int numArgs = 0;
165
0
  LPSTR* pArgs = NULL;
166
0
  char** envp = NULL;
167
0
  char* filename = NULL;
168
0
  HANDLE thread = NULL;
169
0
  HANDLE process = NULL;
170
0
  WINPR_ACCESS_TOKEN* token = NULL;
171
0
  LPTCH lpszEnvironmentBlock = NULL;
172
0
  BOOL ret = FALSE;
173
0
  sigset_t oldSigMask;
174
0
  sigset_t newSigMask;
175
0
  BOOL restoreSigMask = FALSE;
176
0
  numArgs = 0;
177
0
  lpszEnvironmentBlock = NULL;
178
  /* https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessa
179
   */
180
0
  if (lpCommandLine)
181
0
    pArgs = CommandLineToArgvA(lpCommandLine, &numArgs);
182
0
  else
183
0
    pArgs = CommandLineToArgvA(lpApplicationName, &numArgs);
184
185
0
  if (!pArgs)
186
0
    return FALSE;
187
188
0
  token = (WINPR_ACCESS_TOKEN*)hToken;
189
190
0
  if (lpEnvironment)
191
0
  {
192
0
    envp = EnvironmentBlockToEnvpA(lpEnvironment);
193
0
  }
194
0
  else
195
0
  {
196
0
    lpszEnvironmentBlock = GetEnvironmentStrings();
197
198
0
    if (!lpszEnvironmentBlock)
199
0
      goto finish;
200
201
0
    envp = EnvironmentBlockToEnvpA(lpszEnvironmentBlock);
202
0
  }
203
204
0
  if (!envp)
205
0
    goto finish;
206
207
0
  filename = FindApplicationPath(pArgs[0]);
208
209
0
  if (NULL == filename)
210
0
    goto finish;
211
212
  /* block all signals so that the child can safely reset the caller's handlers */
213
0
  sigfillset(&newSigMask);
214
0
  restoreSigMask = !pthread_sigmask(SIG_SETMASK, &newSigMask, &oldSigMask);
215
  /* fork and exec */
216
0
  pid = fork();
217
218
0
  if (pid < 0)
219
0
  {
220
    /* fork failure */
221
0
    goto finish;
222
0
  }
223
224
0
  if (pid == 0)
225
0
  {
226
    /* child process */
227
0
#ifndef __sun
228
0
    int maxfd = 0;
229
0
#endif
230
0
    sigset_t set = { 0 };
231
0
    struct sigaction act = { 0 };
232
    /* set default signal handlers */
233
0
    act.sa_handler = SIG_DFL;
234
0
    act.sa_flags = 0;
235
0
    sigemptyset(&act.sa_mask);
236
237
0
    for (int sig = 1; sig < NSIG; sig++)
238
0
      sigaction(sig, &act, NULL);
239
240
    /* unblock all signals */
241
0
    sigfillset(&set);
242
0
    pthread_sigmask(SIG_UNBLOCK, &set, NULL);
243
244
0
    if (lpStartupInfo)
245
0
    {
246
0
      int handle_fd = 0;
247
0
      handle_fd = winpr_Handle_getFd(lpStartupInfo->hStdOutput);
248
249
0
      if (handle_fd != -1)
250
0
        dup2(handle_fd, STDOUT_FILENO);
251
252
0
      handle_fd = winpr_Handle_getFd(lpStartupInfo->hStdError);
253
254
0
      if (handle_fd != -1)
255
0
        dup2(handle_fd, STDERR_FILENO);
256
257
0
      handle_fd = winpr_Handle_getFd(lpStartupInfo->hStdInput);
258
259
0
      if (handle_fd != -1)
260
0
        dup2(handle_fd, STDIN_FILENO);
261
0
    }
262
263
#ifdef __sun
264
    closefrom(3);
265
#else
266
#ifdef F_MAXFD // on some BSD derivates
267
    maxfd = fcntl(0, F_MAXFD);
268
#else
269
0
    {
270
0
      const long rc = sysconf(_SC_OPEN_MAX);
271
0
      if ((rc < INT32_MIN) || (rc > INT32_MAX))
272
0
        goto finish;
273
0
      maxfd = (int)rc;
274
0
    }
275
0
#endif
276
277
0
    for (int fd = 3; fd < maxfd; fd++)
278
0
      close(fd);
279
280
0
#endif // __sun
281
282
0
    if (token)
283
0
    {
284
0
      if (token->GroupId)
285
0
      {
286
0
        int rc = setgid((gid_t)token->GroupId);
287
288
0
        if (rc < 0)
289
0
        {
290
0
        }
291
0
        else
292
0
        {
293
0
          initgroups(token->Username, (gid_t)token->GroupId);
294
0
        }
295
0
      }
296
297
0
      if (token->UserId)
298
0
      {
299
0
        int rc = setuid((uid_t)token->UserId);
300
0
        if (rc != 0)
301
0
          goto finish;
302
0
      }
303
0
    }
304
305
    /* TODO: add better cwd handling and error checking */
306
0
    if (lpCurrentDirectory && strlen(lpCurrentDirectory) > 0)
307
0
    {
308
0
      int rc = chdir(lpCurrentDirectory);
309
0
      if (rc != 0)
310
0
        goto finish;
311
0
    }
312
313
0
    if (execve(filename, pArgs, envp) < 0)
314
0
    {
315
      /* execve failed - end the process */
316
0
      _exit(1);
317
0
    }
318
0
  }
319
0
  else
320
0
  {
321
    /* parent process */
322
0
  }
323
324
0
  process = CreateProcessHandle(pid);
325
326
0
  if (!process)
327
0
  {
328
0
    goto finish;
329
0
  }
330
331
0
  thread = CreateNoneHandle();
332
333
0
  if (!thread)
334
0
  {
335
0
    ProcessHandleCloseHandle(process);
336
0
    goto finish;
337
0
  }
338
339
0
  lpProcessInformation->hProcess = process;
340
0
  lpProcessInformation->hThread = thread;
341
0
  lpProcessInformation->dwProcessId = (DWORD)pid;
342
0
  lpProcessInformation->dwThreadId = (DWORD)pid;
343
0
  ret = TRUE;
344
0
finish:
345
346
  /* restore caller's original signal mask */
347
0
  if (restoreSigMask)
348
0
    pthread_sigmask(SIG_SETMASK, &oldSigMask, NULL);
349
350
0
  free(filename);
351
0
  free((void*)pArgs);
352
353
0
  if (lpszEnvironmentBlock)
354
0
    FreeEnvironmentStrings(lpszEnvironmentBlock);
355
356
0
  if (envp)
357
0
  {
358
0
    int i = 0;
359
360
0
    while (envp[i])
361
0
    {
362
0
      free(envp[i]);
363
0
      i++;
364
0
    }
365
366
0
    free((void*)envp);
367
0
  }
368
369
0
  return ret;
370
0
}
371
372
BOOL CreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine,
373
                    LPSECURITY_ATTRIBUTES lpProcessAttributes,
374
                    LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles,
375
                    DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory,
376
                    LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
377
0
{
378
0
  return CreateProcessExA(NULL, 0, lpApplicationName, lpCommandLine, lpProcessAttributes,
379
0
                          lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
380
0
                          lpCurrentDirectory, lpStartupInfo, lpProcessInformation);
381
0
}
382
383
BOOL CreateProcessW(WINPR_ATTR_UNUSED LPCWSTR lpApplicationName,
384
                    WINPR_ATTR_UNUSED LPWSTR lpCommandLine,
385
                    WINPR_ATTR_UNUSED LPSECURITY_ATTRIBUTES lpProcessAttributes,
386
                    WINPR_ATTR_UNUSED LPSECURITY_ATTRIBUTES lpThreadAttributes,
387
                    WINPR_ATTR_UNUSED BOOL bInheritHandles, WINPR_ATTR_UNUSED DWORD dwCreationFlags,
388
                    WINPR_ATTR_UNUSED LPVOID lpEnvironment,
389
                    WINPR_ATTR_UNUSED LPCWSTR lpCurrentDirectory,
390
                    WINPR_ATTR_UNUSED LPSTARTUPINFOW lpStartupInfo,
391
                    WINPR_ATTR_UNUSED LPPROCESS_INFORMATION lpProcessInformation)
392
0
{
393
0
  WLog_ERR("TODO", "TODO: implement");
394
0
  return FALSE;
395
0
}
396
397
BOOL CreateProcessAsUserA(HANDLE hToken, LPCSTR lpApplicationName, LPSTR lpCommandLine,
398
                          LPSECURITY_ATTRIBUTES lpProcessAttributes,
399
                          LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles,
400
                          DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory,
401
                          LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
402
0
{
403
0
  return CreateProcessExA(hToken, 0, lpApplicationName, lpCommandLine, lpProcessAttributes,
404
0
                          lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
405
0
                          lpCurrentDirectory, lpStartupInfo, lpProcessInformation);
406
0
}
407
408
BOOL CreateProcessAsUserW(WINPR_ATTR_UNUSED HANDLE hToken,
409
                          WINPR_ATTR_UNUSED LPCWSTR lpApplicationName,
410
                          WINPR_ATTR_UNUSED LPWSTR lpCommandLine,
411
                          WINPR_ATTR_UNUSED LPSECURITY_ATTRIBUTES lpProcessAttributes,
412
                          WINPR_ATTR_UNUSED LPSECURITY_ATTRIBUTES lpThreadAttributes,
413
                          WINPR_ATTR_UNUSED BOOL bInheritHandles,
414
                          WINPR_ATTR_UNUSED DWORD dwCreationFlags,
415
                          WINPR_ATTR_UNUSED LPVOID lpEnvironment,
416
                          WINPR_ATTR_UNUSED LPCWSTR lpCurrentDirectory,
417
                          WINPR_ATTR_UNUSED LPSTARTUPINFOW lpStartupInfo,
418
                          WINPR_ATTR_UNUSED LPPROCESS_INFORMATION lpProcessInformation)
419
0
{
420
0
  WLog_ERR("TODO", "TODO: implement");
421
0
  return FALSE;
422
0
}
423
424
BOOL CreateProcessWithLogonA(
425
    WINPR_ATTR_UNUSED LPCSTR lpUsername, WINPR_ATTR_UNUSED LPCSTR lpDomain,
426
    WINPR_ATTR_UNUSED LPCSTR lpPassword, WINPR_ATTR_UNUSED DWORD dwLogonFlags,
427
    WINPR_ATTR_UNUSED LPCSTR lpApplicationName, WINPR_ATTR_UNUSED LPSTR lpCommandLine,
428
    WINPR_ATTR_UNUSED DWORD dwCreationFlags, WINPR_ATTR_UNUSED LPVOID lpEnvironment,
429
    WINPR_ATTR_UNUSED LPCSTR lpCurrentDirectory, WINPR_ATTR_UNUSED LPSTARTUPINFOA lpStartupInfo,
430
    WINPR_ATTR_UNUSED LPPROCESS_INFORMATION lpProcessInformation)
431
0
{
432
0
  WLog_ERR("TODO", "TODO: implement");
433
0
  return FALSE;
434
0
}
435
436
BOOL CreateProcessWithLogonW(
437
    WINPR_ATTR_UNUSED LPCWSTR lpUsername, WINPR_ATTR_UNUSED LPCWSTR lpDomain,
438
    WINPR_ATTR_UNUSED LPCWSTR lpPassword, WINPR_ATTR_UNUSED DWORD dwLogonFlags,
439
    WINPR_ATTR_UNUSED LPCWSTR lpApplicationName, WINPR_ATTR_UNUSED LPWSTR lpCommandLine,
440
    WINPR_ATTR_UNUSED DWORD dwCreationFlags, WINPR_ATTR_UNUSED LPVOID lpEnvironment,
441
    WINPR_ATTR_UNUSED LPCWSTR lpCurrentDirectory, WINPR_ATTR_UNUSED LPSTARTUPINFOW lpStartupInfo,
442
    WINPR_ATTR_UNUSED LPPROCESS_INFORMATION lpProcessInformation)
443
0
{
444
0
  WLog_ERR("TODO", "TODO: implement");
445
0
  return FALSE;
446
0
}
447
448
BOOL CreateProcessWithTokenA(WINPR_ATTR_UNUSED HANDLE hToken, WINPR_ATTR_UNUSED DWORD dwLogonFlags,
449
                             LPCSTR lpApplicationName, LPSTR lpCommandLine, DWORD dwCreationFlags,
450
                             LPVOID lpEnvironment, LPCSTR lpCurrentDirectory,
451
                             LPSTARTUPINFOA lpStartupInfo,
452
                             LPPROCESS_INFORMATION lpProcessInformation)
453
0
{
454
0
  return CreateProcessExA(NULL, 0, lpApplicationName, lpCommandLine, NULL, NULL, FALSE,
455
0
                          dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo,
456
0
                          lpProcessInformation);
457
0
}
458
459
BOOL CreateProcessWithTokenW(WINPR_ATTR_UNUSED HANDLE hToken, WINPR_ATTR_UNUSED DWORD dwLogonFlags,
460
                             WINPR_ATTR_UNUSED LPCWSTR lpApplicationName,
461
                             WINPR_ATTR_UNUSED LPWSTR lpCommandLine,
462
                             WINPR_ATTR_UNUSED DWORD dwCreationFlags,
463
                             WINPR_ATTR_UNUSED LPVOID lpEnvironment,
464
                             WINPR_ATTR_UNUSED LPCWSTR lpCurrentDirectory,
465
                             WINPR_ATTR_UNUSED LPSTARTUPINFOW lpStartupInfo,
466
                             WINPR_ATTR_UNUSED LPPROCESS_INFORMATION lpProcessInformation)
467
0
{
468
0
  WLog_ERR("TODO", "TODO: implement");
469
0
  return FALSE;
470
0
}
471
472
VOID ExitProcess(UINT uExitCode)
473
0
{
474
  // NOLINTNEXTLINE(concurrency-mt-unsafe)
475
0
  exit((int)uExitCode);
476
0
}
477
478
BOOL GetExitCodeProcess(HANDLE hProcess, LPDWORD lpExitCode)
479
0
{
480
0
  WINPR_PROCESS* process = NULL;
481
482
0
  if (!hProcess)
483
0
    return FALSE;
484
485
0
  if (!lpExitCode)
486
0
    return FALSE;
487
488
0
  process = (WINPR_PROCESS*)hProcess;
489
0
  *lpExitCode = process->dwExitCode;
490
0
  return TRUE;
491
0
}
492
493
HANDLE _GetCurrentProcess(VOID)
494
0
{
495
0
  WLog_ERR("TODO", "TODO: implement");
496
0
  return NULL;
497
0
}
498
499
DWORD GetCurrentProcessId(VOID)
500
0
{
501
0
  return ((DWORD)getpid());
502
0
}
503
504
BOOL TerminateProcess(HANDLE hProcess, WINPR_ATTR_UNUSED UINT uExitCode)
505
0
{
506
0
  WINPR_PROCESS* process = NULL;
507
0
  process = (WINPR_PROCESS*)hProcess;
508
509
0
  if (!process || (process->pid <= 0))
510
0
    return FALSE;
511
512
0
  if (kill(process->pid, SIGTERM))
513
0
    return FALSE;
514
515
0
  return TRUE;
516
0
}
517
518
static BOOL ProcessHandleCloseHandle(HANDLE handle)
519
0
{
520
0
  WINPR_PROCESS* process = (WINPR_PROCESS*)handle;
521
0
  WINPR_ASSERT(process);
522
0
  if (process->fd >= 0)
523
0
  {
524
0
    close(process->fd);
525
0
    process->fd = -1;
526
0
  }
527
0
  free(process);
528
0
  return TRUE;
529
0
}
530
531
static BOOL ProcessHandleIsHandle(HANDLE handle)
532
0
{
533
0
  return WINPR_HANDLE_IS_HANDLED(handle, HANDLE_TYPE_PROCESS, FALSE);
534
0
}
535
536
static int ProcessGetFd(HANDLE handle)
537
0
{
538
0
  WINPR_PROCESS* process = (WINPR_PROCESS*)handle;
539
540
0
  if (!ProcessHandleIsHandle(handle))
541
0
    return -1;
542
543
0
  return process->fd;
544
0
}
545
546
static DWORD ProcessCleanupHandle(HANDLE handle)
547
0
{
548
0
  WINPR_PROCESS* process = (WINPR_PROCESS*)handle;
549
550
0
  WINPR_ASSERT(process);
551
0
  if (process->fd > 0)
552
0
  {
553
0
    if (waitpid(process->pid, &process->status, WNOHANG) == process->pid)
554
0
      process->dwExitCode = (DWORD)process->status;
555
0
  }
556
0
  return WAIT_OBJECT_0;
557
0
}
558
559
static HANDLE_OPS ops = { ProcessHandleIsHandle,
560
                        ProcessHandleCloseHandle,
561
                        ProcessGetFd,
562
                        ProcessCleanupHandle, /* CleanupHandle */
563
                        NULL,
564
                        NULL,
565
                        NULL,
566
                        NULL,
567
                        NULL,
568
                        NULL,
569
                        NULL,
570
                        NULL,
571
                        NULL,
572
                        NULL,
573
                        NULL,
574
                        NULL,
575
                        NULL,
576
                        NULL,
577
                        NULL,
578
                        NULL,
579
                        NULL };
580
581
static int pidfd_open(pid_t pid)
582
0
{
583
0
#ifdef __linux__
584
#if !defined(__NR_pidfd_open)
585
#define __NR_pidfd_open 434
586
#endif /* __NR_pidfd_open */
587
588
0
#ifndef PIDFD_NONBLOCK
589
0
#define PIDFD_NONBLOCK O_NONBLOCK
590
0
#endif /* PIDFD_NONBLOCK */
591
592
0
  long fd = syscall(__NR_pidfd_open, pid, PIDFD_NONBLOCK);
593
0
  if (fd < 0 && errno == EINVAL)
594
0
  {
595
    /* possibly PIDFD_NONBLOCK is not supported, let's try to create a pidfd and set it
596
     * non blocking afterward */
597
0
    int flags = 0;
598
0
    fd = syscall(__NR_pidfd_open, pid, 0);
599
0
    if ((fd < 0) || (fd > INT32_MAX))
600
0
      return -1;
601
602
0
    flags = fcntl((int)fd, F_GETFL);
603
0
    if ((flags < 0) || fcntl((int)fd, F_SETFL, flags | O_NONBLOCK) < 0)
604
0
    {
605
0
      close((int)fd);
606
0
      fd = -1;
607
0
    }
608
0
  }
609
0
  if ((fd < 0) || (fd > INT32_MAX))
610
0
    return -1;
611
0
  return (int)fd;
612
#else
613
  return -1;
614
#endif
615
0
}
616
617
HANDLE CreateProcessHandle(pid_t pid)
618
0
{
619
0
  WINPR_PROCESS* process = NULL;
620
0
  process = (WINPR_PROCESS*)calloc(1, sizeof(WINPR_PROCESS));
621
622
0
  if (!process)
623
0
    return NULL;
624
625
0
  process->pid = pid;
626
0
  process->common.Type = HANDLE_TYPE_PROCESS;
627
0
  process->common.ops = &ops;
628
0
  process->fd = pidfd_open(pid);
629
0
  if (process->fd >= 0)
630
0
    process->common.Mode = WINPR_FD_READ;
631
0
  return (HANDLE)process;
632
0
}
633
634
#endif