-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathlinux.h
More file actions
123 lines (106 loc) · 4.17 KB
/
linux.h
File metadata and controls
123 lines (106 loc) · 4.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include <limits.h> // for PATH_MAX
#include <stdio.h> // for snprintf
#include <stdlib.h> // for NULL, size_t, free
#include <string.h> // for strcat, strcpy, strdup, strlen, strtok
#include <unistd.h> // for access
#include "logging.h"
#include "common.h"
#define OS_NAME "linux"
int is_command_available(const char *command) {
return access(command, X_OK) == 0;
}
int find_executable(const char *name, char *path_buf, size_t buf_size) {
char *path_env = getenv("PATH");
if (path_env == NULL) return 0;
char *path_copy = strdup(path_env);
if (path_copy == NULL) return 0;
char *dir = strtok(path_copy, ":");
while (dir) {
snprintf(path_buf, buf_size, "%s/%s", dir, name);
if (access(path_buf, X_OK) == 0) {
free(path_copy);
return 1;
}
dir = strtok(NULL, ":");
}
free(path_copy);
return 0;
}
// ===========================================================
// common.h FUNCTION IMPLEMENTATIONS
// ===========================================================
void setup(const int argc, const char *argv[]) {}
void teardown() {}
void runloop_config(const char *directive) {}
void runloop_run(const char *mode) {}
void runloop_stop() {}
int init_threads() {
LOG_INFO("LINUX", "Running XInitThreads");
void *libX11Handle = lib_open("libX11.so");
if (libX11Handle == NULL) {
FAIL(ERROR_MISSING_FUNCTION,
"Could not find X11 library, not running XInitThreads.");
}
void (*XInitThreads)() = lib_sym(libX11Handle, "XInitThreads");
if (XInitThreads == NULL) {
lib_close(libX11Handle);
FAIL(ERROR_MISSING_FUNCTION,
"Could not find XInitThreads in X11 library: %s", lib_error());
}
XInitThreads();
return SUCCESS;
}
/*
* The Linux way of displaying a graphical error message.
*
* It looks for a utility program in decreasing order of idealness:
* zenity, then kdialog, then xmessage, and finally notify-send.
* If it finds one, it invokes it via execlp to display the message;
* if not, it falls back to plain old printf.
*/
void show_alert(const char *title, const char *message) {
char exe[PATH_MAX];
if (find_executable("zenity", exe, sizeof(exe))) {
char *titleArg = malloc_or_die(strlen(title) + 9, "zenity title"); // --title={message}
strcpy(titleArg, "--title=");
strcat(titleArg, title);
char *textArg = malloc_or_die(strlen(message) + 8, "zenity text"); // --text={message}
strcpy(textArg, "--text=");
strcat(textArg, message);
LOG_INFO("LINUX", "'%s' '%s' '%s' '%s'", exe, "--error", titleArg, textArg);
execlp(exe, "zenity", "--error", titleArg, textArg, (char *)NULL);
// Note: execlp replaces the process, so the free calls are orphaned.
free(titleArg);
free(textArg);
} else if (find_executable("kdialog", exe, sizeof(exe))) {
char *titleArg = malloc_or_die(strlen(title) + 9, "kdialog title"); // --title={message}
strcpy("--title=", titleArg);
strcat((char *)title, titleArg);
LOG_INFO("LINUX", "'%s' '%s' '%s' '%s'", exe, "--sorry", titleArg, message);
execlp(exe, "kdialog", "--sorry", titleArg, message, (char *)NULL);
// Note: execlp replaces the process, so the free calls are orphaned.
free(titleArg);
} else if (find_executable("xmessage", exe, sizeof(exe))) {
LOG_INFO("LINUX", "'%s' '%s' '%s' '%s' '%s'", exe,
"-buttons", "OK:0", "-nearmouse", message);
execlp(exe, "xmessage",
"-buttons", "OK:0", "-nearmouse", message, (char *)NULL);
} else if (find_executable("notify-send", exe, sizeof(exe))) {
LOG_INFO("LINUX", "'%s' '%s' '%s' '%s' '%s' '%s'", exe,
"-a", title, "-c", "im.error", message);
execlp(exe, "notify-send",
"-a", title, "-c", "im.error", message, (char *)NULL);
} else {
printf("%s\n", message);
}
}
/*
* The Linux way of launching a runtime.
*
* It calls the given launch function directly. The epitome of elegance. ^_^
*/
int launch(const LaunchFunc launch_runtime,
const size_t argc, const char **argv)
{
return launch_runtime(argc, argv);
}