aboutsummaryrefslogtreecommitdiff
path: root/src/openrc-run/openrc-run.c
diff options
context:
space:
mode:
authorAnna (navi) Figueiredo Gomes <navi@vlhl.dev>2023-03-14 19:03:52 -0300
committerAnna (navi) Figueiredo Gomes <navi@vlhl.dev>2023-10-19 10:56:54 +0200
commit9efa44579fd1f60a4c9ace264bb0b968ccb0f7ea (patch)
tree71f6d00e0fe41ae3ac338c6dba21c75f7cb74528 /src/openrc-run/openrc-run.c
parentb80971ce08dd080529efaf694afc67846e0748b8 (diff)
openrc: Add support for user services.
Modifies many functions where filesystem paths were hardcoded. In non-user-services mode, they still are. In user-services mode, they are allocated, since XDG_ dirs are to be set via environment variables. Signed-off-by: Anna (navi) Figueiredo Gomes <navi@vlhl.dev>
Diffstat (limited to 'src/openrc-run/openrc-run.c')
-rw-r--r--src/openrc-run/openrc-run.c77
1 files changed, 64 insertions, 13 deletions
diff --git a/src/openrc-run/openrc-run.c b/src/openrc-run/openrc-run.c
index 6b28a809..6ce5ddec 100644
--- a/src/openrc-run/openrc-run.c
+++ b/src/openrc-run/openrc-run.c
@@ -54,7 +54,7 @@
#include "_usage.h"
#include "helpers.h"
-#define PREFIX_LOCK RC_SVCDIR "/prefix.lock"
+#define PREFIX_LOCK_FILE "/prefix.lock"
#define WAIT_INTERVAL 20000000 /* usecs to poll the lock file */
#define WAIT_TIMEOUT 60 /* seconds until we timeout */
@@ -164,8 +164,21 @@ static void
unhotplug(void)
{
char *file = NULL;
+ char *svcdir = RC_SVCDIR;
+#ifdef RC_USER_SERVICES
+ if (rc_is_user()) {
+ svcdir = rc_user_svcdir();
+ }
+#endif
+
+ xasprintf(&file, "%s/hotplugged/%s", svcdir, applet);
+
+#ifdef RC_USER_SERVICES
+ if (rc_is_user()) {
+ free(svcdir);
+ }
+#endif
- xasprintf(&file, RC_SVCDIR "/hotplugged/%s", applet);
if (exists(file) && unlink(file) != 0)
eerror("%s: unlink `%s': %s", applet, file, strerror(errno));
free(file);
@@ -286,12 +299,25 @@ write_prefix(const char *buffer, size_t bytes, bool *prefixed)
const char *ec_normal = ecolor(ECOLOR_NORMAL);
ssize_t ret = 0;
int fd = fileno(stdout), lock_fd = -1;
+ char *prefix_lock = RC_SVCDIR PREFIX_LOCK_FILE;
+#ifdef RC_USER_SERVICES
+ if (rc_is_user()) {
+ char *svcdir = rc_user_svcdir();
+ xasprintf(&prefix_lock, "%s/%s", svcdir, PREFIX_LOCK_FILE);
+ free(svcdir);
+ }
+#endif
/*
* Lock the prefix.
- * open() may fail here when running as user, as RC_SVCDIR may not be writable.
*/
- lock_fd = open(PREFIX_LOCK, O_WRONLY | O_CREAT, 0664);
+ lock_fd = open(prefix_lock, O_WRONLY | O_CREAT, 0664);
+
+#ifdef RC_USER_SERVICES
+ if (rc_is_user()) {
+ free(prefix_lock);
+ }
+#endif
if (lock_fd != -1) {
while (flock(lock_fd, LOCK_EX) != 0) {
@@ -350,6 +376,13 @@ svc_exec(const char *arg1, const char *arg2)
int slave_tty;
sigset_t sigchldmask;
sigset_t oldmask;
+ char *runsh;
+ char *svcdir = RC_SVCDIR;
+#ifdef RC_USER_SERVICES
+ if (rc_is_user()) {
+ svcdir = rc_user_svcdir();
+ }
+#endif
/* Setup our signal pipe */
if (pipe(signal_pipe) == -1)
@@ -390,20 +423,19 @@ svc_exec(const char *arg1, const char *arg2)
dup2(slave_tty, STDERR_FILENO);
}
- if (exists(RC_SVCDIR "/openrc-run.sh")) {
+ xasprintf(&runsh, "%s/%s", svcdir, "openrc-run.sh");
+ if (exists(runsh)) {
if (arg2)
einfov("Executing: %s %s %s %s %s",
- RC_SVCDIR "/openrc-run.sh", RC_SVCDIR "/openrc-run.sh",
+ runsh, runsh,
service, arg1, arg2);
else
einfov("Executing: %s %s %s %s",
- RC_SVCDIR "/openrc-run.sh", RC_SVCDIR "/openrc-run.sh",
+ runsh, runsh,
service, arg1);
- execl(RC_SVCDIR "/openrc-run.sh",
- RC_SVCDIR "/openrc-run.sh",
- service, arg1, arg2, (char *) NULL);
- eerror("%s: exec `" RC_SVCDIR "/openrc-run.sh': %s",
- service, strerror(errno));
+ execl(runsh, runsh, service, arg1, arg2, (char *) NULL);
+ eerror("%s: exec '%s': %s",
+ service, runsh, strerror(errno));
_exit(EXIT_FAILURE);
} else {
if (arg2)
@@ -423,8 +455,15 @@ svc_exec(const char *arg1, const char *arg2)
service, strerror(errno));
_exit(EXIT_FAILURE);
}
+ free(runsh);
}
+#ifdef RC_USER_SERVICES
+ if (rc_is_user()) {
+ free(svcdir);
+ }
+#endif
+
buffer = xmalloc(sizeof(char) * BUFSIZ);
fd[0].fd = signal_pipe[0];
fd[0].events = fd[1].events = POLLIN;
@@ -500,6 +539,12 @@ svc_wait(const char *svc)
bool forever = false;
RC_STRINGLIST *keywords;
struct timespec interval, timeout, warn;
+ char *svcdir = RC_SVCDIR;
+#ifdef RC_USER_SERVICES
+ if (rc_is_user()) {
+ svcdir = rc_user_svcdir();
+ }
+#endif
/* Some services don't have a timeout, like fsck */
keywords = rc_deptree_depend(deptree, svc, "keyword");
@@ -508,7 +553,13 @@ svc_wait(const char *svc)
forever = true;
rc_stringlist_free(keywords);
- xasprintf(&file, RC_SVCDIR "/exclusive/%s", basename_c(svc));
+ xasprintf(&file, "%s/exclusive/%s", svcdir, basename_c(svc));
+
+#ifdef RC_USER_SERVICES
+ if (rc_is_user()) {
+ free(svcdir);
+ }
+#endif
interval.tv_sec = 0;
interval.tv_nsec = WAIT_INTERVAL;