From 26314e983b963a4252154aef25406acdca50b423 Mon Sep 17 00:00:00 2001 From: "Anna (navi) Figueiredo Gomes" Date: Sat, 20 Jul 2024 18:09:26 +0200 Subject: openrc-run.c: allow --user on shebangs Signed-off-by: Anna (navi) Figueiredo Gomes --- src/openrc-run/openrc-run.c | 92 ++++++++++++++++++++++++--------------------- 1 file changed, 49 insertions(+), 43 deletions(-) diff --git a/src/openrc-run/openrc-run.c b/src/openrc-run/openrc-run.c index 46c9364a..11c38017 100644 --- a/src/openrc-run/openrc-run.c +++ b/src/openrc-run/openrc-run.c @@ -1168,20 +1168,26 @@ int main(int argc, char **argv) struct stat stbuf; /* Show help if insufficient args */ - if (argc < 2 || !exists(argv[1])) { + if (argc < 2) { fprintf(stderr, "openrc-run should not be run directly\n"); exit(EXIT_FAILURE); } - if (rc_yesno(getenv("RC_USER_SERVICES"))) - rc_set_user(); + /* allow #!/sbin/openrc-run --user as a shebang */ + if (strcmp(argv[1], "--user") == 0) { + char *tmp = argv[1]; + argv[1] = argv[2]; + argv[2] = tmp; + } if (stat(argv[1], &stbuf) != 0) { - fprintf(stderr, "openrc-run `%s': %s\n", - argv[1], strerror(errno)); + fprintf(stderr, "openrc-run '%s': %s\n", argv[1], strerror(errno)); exit(EXIT_FAILURE); } + if (rc_yesno(getenv("RC_USER_SERVICES"))) + rc_set_user(); + /* We need to work out the real full path to our service. * multiplexed services must point to a target in a init dir. */ path = realpath(argv[1], NULL); @@ -1203,6 +1209,44 @@ int main(int argc, char **argv) service = normalize_path(argv[1]); applet = basename_c(service); + /* Ok, we are ready to go, so setup selinux if applicable */ + selinux_setup(argv); + + deps = true; + + /* Punt the first arg as its our service name */ + argc--; + argv++; + + /* Right then, parse any options there may be */ + while ((opt = getopt_long(argc, argv, getoptstring, + longopts, (int *)0)) != -1) + switch (opt) { + case 'd': + setenv("RC_DEBUG", "YES", 1); + break; + case 'l': + exclusive_fd = atoi(optarg); + fcntl(exclusive_fd, F_SETFD, + fcntl(exclusive_fd, F_GETFD, 0) | FD_CLOEXEC); + break; + case 's': + if (!(rc_service_state(service) & RC_SERVICE_STARTED)) + exit(EXIT_FAILURE); + break; + case 'S': + if (!(rc_service_state(service) & RC_SERVICE_STOPPED)) + exit(EXIT_FAILURE); + break; + case 'D': + deps = false; + break; + case 'Z': + dry_run = true; + break; + case_RC_COMMON_GETOPT + } + atexit(cleanup); if (argc < 3) @@ -1255,44 +1299,6 @@ int main(int argc, char **argv) eprefix(prefix); } - /* Ok, we are ready to go, so setup selinux if applicable */ - selinux_setup(argv); - - deps = true; - - /* Punt the first arg as its our service name */ - argc--; - argv++; - - /* Right then, parse any options there may be */ - while ((opt = getopt_long(argc, argv, getoptstring, - longopts, (int *)0)) != -1) - switch (opt) { - case 'd': - setenv("RC_DEBUG", "YES", 1); - break; - case 'l': - exclusive_fd = atoi(optarg); - fcntl(exclusive_fd, F_SETFD, - fcntl(exclusive_fd, F_GETFD, 0) | FD_CLOEXEC); - break; - case 's': - if (!(rc_service_state(service) & RC_SERVICE_STARTED)) - exit(EXIT_FAILURE); - break; - case 'S': - if (!(rc_service_state(service) & RC_SERVICE_STOPPED)) - exit(EXIT_FAILURE); - break; - case 'D': - deps = false; - break; - case 'Z': - dry_run = true; - break; - case_RC_COMMON_GETOPT - } - if (rc_yesno(getenv("RC_NODEPS"))) deps = false; -- cgit v1.2.3