diff options
Diffstat (limited to 'src/openrc-run')
-rw-r--r-- | src/openrc-run/meson.build | 4 | ||||
-rw-r--r-- | src/openrc-run/openrc-run.c | 77 |
2 files changed, 66 insertions, 15 deletions
diff --git a/src/openrc-run/meson.build b/src/openrc-run/meson.build index 2e4b29a0..5de60456 100644 --- a/src/openrc-run/meson.build +++ b/src/openrc-run/meson.build @@ -1,6 +1,6 @@ executable('openrc-run', ['openrc-run.c', misc_c, plugin_c, selinux_c, usage_c, version_h], - c_args : [cc_audit_flags, cc_branding_flags, cc_pam_flags, cc_selinux_flags], + c_args : [cc_audit_flags, cc_branding_flags, cc_pam_flags, cc_selinux_flags, cc_user_services_flags], link_with: [libeinfo, librc], dependencies: [audit_dep, dl_dep, pam_dep, pam_misc_dep, selinux_dep, util_dep, crypt_dep], include_directories: [incdir, einfo_incdir, rc_incdir], @@ -9,7 +9,7 @@ executable('openrc-run', executable('runscript', ['openrc-run.c', misc_c, plugin_c, selinux_c, usage_c, version_h], - c_args : [cc_audit_flags, cc_branding_flags, cc_pam_flags, cc_selinux_flags], + c_args : [cc_audit_flags, cc_branding_flags, cc_pam_flags, cc_selinux_flags, cc_user_services_flags], link_with: [libeinfo, librc], dependencies: [audit_dep, dl_dep, pam_dep, pam_misc_dep, selinux_dep, util_dep, crypt_dep], include_directories: [incdir, einfo_incdir, rc_incdir], 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; |