The open source OpenXR runtime
1
2// Copyright 2019-2020, Collabora, Ltd.
3// SPDX-License-Identifier: BSL-1.0
4/*!
5 * @file
6 * @brief Simple process handling
7 * @author Christoph Haag <christoph.haag@collabora.com>
8 * @ingroup aux_util
9 */
10
11#include "xrt/xrt_config.h"
12#include "xrt/xrt_config_build.h"
13
14#ifdef XRT_OS_LINUX
15
16#ifdef XRT_HAVE_LIBBSD
17#include <bsd/libutil.h>
18#endif
19
20#include <limits.h>
21
22#include <errno.h>
23#include <stdbool.h>
24#include "u_file.h"
25#include "u_logging.h"
26
27XRT_MAYBE_UNUSED static inline int
28get_pidfile_path(char *buf)
29{
30 int size = u_file_get_path_in_runtime_dir(XRT_IPC_SERVICE_PID_FILENAME, buf, PATH_MAX);
31 if (size == -1) {
32 U_LOG_W("Failed to determine runtime dir, not creating pidfile");
33 return -1;
34 }
35 return 0;
36}
37
38#endif
39
40#include "u_misc.h"
41
42struct u_process
43{
44#ifdef XRT_HAVE_LIBBSD
45 struct pidfh *pfh;
46#else
47 int pid;
48#endif
49};
50
51struct u_process *
52u_process_create_if_not_running(void)
53{
54#ifdef XRT_HAVE_LIBBSD
55 char tmp[PATH_MAX] = {0};
56 if (get_pidfile_path(tmp) < 0) {
57 U_LOG_W("Failed to determine runtime dir, not creating pidfile");
58 return NULL;
59 }
60
61 U_LOG_T("Using pidfile %s", tmp);
62
63 pid_t otherpid;
64 struct pidfh *pfh = pidfile_open(tmp, 0600, &otherpid);
65 if (pfh == NULL) {
66 // other process is locking pid file
67 if (errno == EEXIST) {
68 U_LOG_E("Monado is already running, pid %d", otherpid);
69 }
70 U_LOG_E("Failed to create pidfile: %s", strerror(errno));
71 return NULL;
72 }
73
74 // either new or stale pidfile opened
75 int write_ret = pidfile_write(pfh);
76 if (write_ret != 0) {
77 pidfile_close(pfh);
78 return NULL;
79 }
80
81 struct u_process *ret = U_TYPED_CALLOC(struct u_process);
82 ret->pfh = pfh;
83
84 U_LOG_T("No other Monado instance was running, got new pidfile");
85 return ret;
86#else
87 struct u_process *ret = U_TYPED_CALLOC(struct u_process);
88 //! @todo alternative implementation
89 ret->pid = 0;
90 return ret;
91#endif
92}
93
94void
95u_process_destroy(struct u_process *proc)
96{
97 if (proc == NULL) {
98 return;
99 }
100
101#ifdef XRT_HAVE_LIBBSD
102 pidfile_close(proc->pfh);
103#endif
104 free(proc);
105}