Date: Sat, 4 Aug 2018 14:52:32 +0000 (UTC) From: Edward Tomasz Napierala <trasz@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r337321 - head/sbin/init Message-ID: <201808041452.w74EqWZB035652@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: trasz Date: Sat Aug 4 14:52:32 2018 New Revision: 337321 URL: https://svnweb.freebsd.org/changeset/base/337321 Log: Make it possible for init to execute any executable, not just sh(1) scripts. This means one should be able to eg rewrite their /etc/rc in Python. Reviewed by: kib MFC after: 2 weeks Relnotes: yes Sponsored by: DARPA, AFRL Differential Revision: https://reviews.freebsd.org/D16565 Modified: head/sbin/init/init.c Modified: head/sbin/init/init.c ============================================================================== --- head/sbin/init/init.c Sat Aug 4 14:39:45 2018 (r337320) +++ head/sbin/init/init.c Sat Aug 4 14:52:32 2018 (r337321) @@ -1057,7 +1057,7 @@ static state_func_t run_script(const char *script) { pid_t pid, wpid; - int status; + int error, status; char *argv[4]; const char *shell; struct sigaction sa; @@ -1086,6 +1086,21 @@ run_script(const char *script) #ifdef LOGIN_CAP setprocresources(RESOURCE_RC); #endif + + /* + * Try to directly execute the script first. If it + * fails, try the old method of passing the script path + * to sh(1). Don't complain if it fails because of + * the missing execute bit. + */ + error = access(script, X_OK); + if (error == 0) { + execv(script, argv + 1); + warning("can't exec %s: %m", script); + } else if (errno != EACCES) { + warning("can't access %s: %m", script); + } + execv(shell, argv); stall("can't exec %s for %s: %m", shell, script); _exit(1); /* force single user mode */ @@ -1854,7 +1869,7 @@ static int runshutdown(void) { pid_t pid, wpid; - int status; + int error, status; int shutdowntimeout; size_t len; char *argv[4]; @@ -1897,6 +1912,21 @@ runshutdown(void) #ifdef LOGIN_CAP setprocresources(RESOURCE_RC); #endif + + /* + * Try to directly execute the script first. If it + * fails, try the old method of passing the script path + * to sh(1). Don't complain if it fails because of + * the missing execute bit. + */ + error = access(_path_rundown, X_OK); + if (error == 0) { + execv(_path_rundown, argv + 1); + warning("can't exec %s: %m", _path_rundown); + } else if (errno != EACCES) { + warning("can't access %s: %m", _path_rundown); + } + execv(shell, argv); warning("can't exec %s for %s: %m", shell, _PATH_RUNDOWN); _exit(1); /* force single user mode */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201808041452.w74EqWZB035652>