Punt the dodgy ebuffer code. We now force prefixing for parallel starts which also reduces our variable pollution.
This commit is contained in:
parent
35d860710a
commit
356c41f77c
12
conf.d/rc
12
conf.d/rc
@ -1,16 +1,11 @@
|
||||
# /etc/conf.d/rc: Global config file for the Gentoo RC System
|
||||
|
||||
# Set to "yes" if you want the rc system to try and start services
|
||||
# in parallel for a slight speed improvement.
|
||||
# in parallel for a slight speed improvement. When running in parallel we
|
||||
# prefix the service output with it's name as the output will get
|
||||
# jumbled up.
|
||||
RC_PARALLEL="no"
|
||||
|
||||
# If we're running in parallel then the output of each service is buffered
|
||||
# until the service finishes. This is so the output one service is not mixed
|
||||
# with the output of another service.
|
||||
# To avoid buffering can prefix each line of output to see the service which
|
||||
# it belongs to by setting the RC_PREFIX="yes".
|
||||
RC_PREFIX="no"
|
||||
|
||||
# Set RC_INTERACTIVE to "yes" and you'll be able to press the I key during
|
||||
# boot so you can choose to start specific services. Set to "no" to disable
|
||||
# this feature.
|
||||
@ -25,7 +20,6 @@ RC_VERBOSE="no"
|
||||
# output.
|
||||
RC_QUIET="no"
|
||||
|
||||
|
||||
# Do we allow any started service in the runlevel to satisfy the depedency
|
||||
# or do we want all of them regardless of state? For example, if net.eth0
|
||||
# and net.eth0 are in the default runlevel then with RC_STRICT_DEPEND="no"
|
||||
|
@ -67,20 +67,20 @@ _wait_for_carrier() {
|
||||
# Incase users don't want this nice feature ...
|
||||
[ ${timeout} -le 0 ] && return 0
|
||||
|
||||
[ -n "${RC_EBUFFER}" -o "${RC_PREFIX}" = "yes" ] && efunc=einfo
|
||||
[ "${RC_PARALLEL}" = "yes" ] && efunc=einfo
|
||||
${efunc} "Waiting for carrier (${timeout} seconds) "
|
||||
while [ ${timeout} -gt 0 ] ; do
|
||||
sleep 1
|
||||
if _has_carrier ; then
|
||||
[ -z "${RC_EBUFFER}" ] && echo
|
||||
[ "${efunc}" = "einfon" ] && echo
|
||||
eend 0
|
||||
return 0
|
||||
fi
|
||||
timeout=$((${timeout} - 1))
|
||||
[ -z "${RC_EBUFFER}" -a "${RC_PREFIX}" != "yes" ] && printf "."
|
||||
[ "${efunc}" = "einfon" ] && printf "."
|
||||
done
|
||||
|
||||
[ -z "${RC_EBUFFER}" -a "${RC_PREFIX}" != "yes" ] && echo
|
||||
[ "${efunc}" = "einfon" ] && echo
|
||||
eend 1
|
||||
return 1
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ SYS_WHITELIST = env_whitelist
|
||||
TARGET = $(LIB_TARGETS) $(BIN_TARGETS) $(SBIN_TARGETS) $(PRIV_BIN_TARGETS)
|
||||
|
||||
RCLINKS = einfon einfo ewarnn ewarn eerrorn eerror ebegin eend ewend \
|
||||
eindent eoutdent eflush eval_ecolors \
|
||||
eindent eoutdent eval_ecolors \
|
||||
veinfo vewarn vebegin veend vewend veindent veoutdent \
|
||||
service_starting service_inactive service_started \
|
||||
service_stopping service_stopped \
|
||||
|
@ -67,12 +67,4 @@ void eoutdentv (void);
|
||||
/* Pointer to a string that is always prefixed to einfo/ewarn/error */
|
||||
void eprefix (const char *prefix);
|
||||
|
||||
/* Handy utils to buffer stdout and stderr so our output is always
|
||||
* sane when forking around.
|
||||
* Don't depend on these being here though as we may take a different
|
||||
* approach at a later date. */
|
||||
void ebuffer (const char *file);
|
||||
void eflush (void);
|
||||
void eclose (void);
|
||||
|
||||
#endif
|
||||
|
131
src/libeinfo.c
131
src/libeinfo.c
@ -32,8 +32,6 @@ hidden_proto(eendv)
|
||||
hidden_proto(eerror)
|
||||
hidden_proto(eerrorn)
|
||||
hidden_proto(eerrorx)
|
||||
hidden_proto(eflush)
|
||||
hidden_proto(eclose)
|
||||
hidden_proto(eindent)
|
||||
hidden_proto(eindentv)
|
||||
hidden_proto(einfo)
|
||||
@ -64,8 +62,6 @@ hidden_proto(ewendv)
|
||||
/* How wide can the indent go? */
|
||||
#define INDENT_MAX 40
|
||||
|
||||
#define EBUFFER_LOCK RC_SVCDIR "ebuffer/.lock"
|
||||
|
||||
/* Default colours */
|
||||
#define ECOLOR_GOOD "\033[32;01m"
|
||||
#define ECOLOR_WARN "\033[33;01m"
|
||||
@ -120,10 +116,6 @@ static const char *color_terms[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
/* We use this array to save the stdout/stderr fd's for buffering */
|
||||
static int stdfd[2] = {-1, -1};
|
||||
static FILE *ebfp = NULL;
|
||||
static char ebfile[PATH_MAX] = { '\0' };
|
||||
static const char *term = NULL;
|
||||
static bool term_is_cons25 = false;
|
||||
|
||||
@ -201,126 +193,6 @@ void eprefix (const char *prefix) {
|
||||
_eprefix = prefix;
|
||||
}
|
||||
|
||||
void ebuffer (const char *file)
|
||||
{
|
||||
/* Don't ebuffer if we don't have a file or we already are */
|
||||
if (! file || stdfd[0] >= 0 || ! isatty (fileno (stdout)))
|
||||
return;
|
||||
|
||||
/* Save the current fd's */
|
||||
stdfd[0] = dup (fileno (stdout));
|
||||
stdfd[1] = dup (fileno (stderr));
|
||||
|
||||
if (! (ebfp = fopen (file, "w+"))) {
|
||||
fprintf (stderr, "fopen `%s': %s\n", file, strerror (errno));
|
||||
return;
|
||||
}
|
||||
|
||||
snprintf (ebfile, sizeof (ebfile), "%s", file);
|
||||
|
||||
fflush (stdout);
|
||||
fflush (stderr);
|
||||
|
||||
/* Now redirect stdout and stderr */
|
||||
if ((dup2 (fileno (ebfp), fileno (stdout))) < 0)
|
||||
fprintf (stderr, "dup2: %s", strerror (errno));
|
||||
if ((dup2 (fileno (ebfp), fileno (stderr))) < 0)
|
||||
fprintf (stderr, "dup2: %s", strerror (errno));
|
||||
|
||||
/* Store the filename in our environment so scripts can tell if we're
|
||||
* buffering or not */
|
||||
unsetenv ("RC_EBUFFER");
|
||||
setenv ("RC_EBUFFER", file, 1);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void _eflush (bool reopen)
|
||||
{
|
||||
char buffer[RC_LINEBUFFER];
|
||||
int serrno = errno;
|
||||
|
||||
/* eflush called from an init script? */
|
||||
if (! ebfp) {
|
||||
char *file = getenv ("RC_EBUFFER");
|
||||
if (file)
|
||||
ebfp = fopen (file, "a+");
|
||||
}
|
||||
|
||||
if (! ebfp)
|
||||
return;
|
||||
|
||||
fflush (stdout);
|
||||
fflush (stderr);
|
||||
|
||||
/* Restore stdout and stderr now */
|
||||
if (stdfd[0] >= 0) {
|
||||
dup2 (stdfd[0], fileno (stdout));
|
||||
dup2 (stdfd[1], fileno (stderr));
|
||||
} else {
|
||||
char *tty = getenv ("RC_TTY");
|
||||
if (tty) {
|
||||
freopen (tty, "w+", stdout);
|
||||
dup2 (fileno (stdout), fileno (stderr));
|
||||
}
|
||||
}
|
||||
|
||||
/* Spin until we can lock the ebuffer */
|
||||
while (true) {
|
||||
struct timeval tv;
|
||||
errno = 0;
|
||||
if (mkfifo (EBUFFER_LOCK, 0700) == 0)
|
||||
break;
|
||||
if (errno != EEXIST)
|
||||
eerror ("mkfifo `%s': %s\n", EBUFFER_LOCK, strerror (errno));
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 20000;
|
||||
select (0, NULL, NULL, NULL, &tv);
|
||||
}
|
||||
errno = serrno;
|
||||
|
||||
/* Dump the file to stdout */
|
||||
memset (buffer, 0, RC_LINEBUFFER);
|
||||
if (fseek (ebfp, (off_t) 0, SEEK_SET) < 0)
|
||||
eerror ("fseek: %s", strerror (errno));
|
||||
else {
|
||||
while (fgets (buffer, RC_LINEBUFFER, ebfp))
|
||||
printf ("%s", buffer);
|
||||
}
|
||||
fflush (stdout);
|
||||
fflush (stderr);
|
||||
|
||||
if (unlink (EBUFFER_LOCK))
|
||||
eerror ("unlink `%s': %s", EBUFFER_LOCK, strerror (errno));
|
||||
|
||||
if (reopen) {
|
||||
ftruncate (fileno (ebfp), (off_t) 0);
|
||||
fseek (ebfp, (off_t) 0, SEEK_SET);
|
||||
dup2 (fileno (ebfp), fileno (stdout));
|
||||
dup2 (fileno (ebfp), fileno (stderr));
|
||||
} else {
|
||||
stdfd[0] = -1;
|
||||
stdfd[1] = -1;
|
||||
fclose (ebfp);
|
||||
ebfp = NULL;
|
||||
unlink (ebfile);
|
||||
ebfile[0] = '\0';
|
||||
unsetenv ("RC_EBUFFER");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void eflush () {
|
||||
_eflush (true);
|
||||
}
|
||||
hidden_def(eflush)
|
||||
|
||||
void eclose () {
|
||||
_eflush (false);
|
||||
}
|
||||
hidden_def(eclose)
|
||||
|
||||
static void elog (int level, const char *fmt, va_list ap)
|
||||
{
|
||||
char *e = getenv ("RC_ELOG");
|
||||
@ -518,7 +390,6 @@ void ewarnx (const char *fmt, ...)
|
||||
int retval;
|
||||
va_list ap;
|
||||
|
||||
eclose ();
|
||||
if (fmt && ! is_env ("RC_QUIET", "yes")) {
|
||||
va_start (ap, fmt);
|
||||
elog (LOG_WARNING, fmt, ap);
|
||||
@ -544,7 +415,6 @@ int eerror (const char *fmt, ...)
|
||||
va_end (ap);
|
||||
retval += fprintf (stderr, "\n");
|
||||
|
||||
eflush ();
|
||||
return (retval);
|
||||
}
|
||||
hidden_def(eerror)
|
||||
@ -553,7 +423,6 @@ void eerrorx (const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
eclose ();
|
||||
if (fmt) {
|
||||
va_start (ap, fmt);
|
||||
elog (LOG_ERR, fmt, ap);
|
||||
|
@ -583,7 +583,6 @@ static const char *depdirs[] =
|
||||
RC_SVCDIR "options",
|
||||
RC_SVCDIR "exclusive",
|
||||
RC_SVCDIR "scheduled",
|
||||
RC_SVCDIR "ebuffer",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -113,8 +113,6 @@ void rc_plugin_run (rc_hook_t hook, const char *value)
|
||||
if (rc_in_plugin)
|
||||
return;
|
||||
|
||||
eflush ();
|
||||
|
||||
while (plugin) {
|
||||
if (plugin->hook) {
|
||||
int i;
|
||||
@ -186,8 +184,6 @@ void rc_plugin_run (rc_hook_t hook, const char *value)
|
||||
}
|
||||
plugin = plugin->next;
|
||||
}
|
||||
|
||||
eflush ();
|
||||
}
|
||||
|
||||
void rc_plugin_unload (void)
|
||||
|
2
src/rc.c
2
src/rc.c
@ -211,8 +211,6 @@ static int do_e (int argc, char **argv)
|
||||
eindentv ();
|
||||
else if (strcmp (applet, "veoutdent") == 0)
|
||||
eoutdentv ();
|
||||
else if (strcmp (applet, "eflush") == 0)
|
||||
eflush ();
|
||||
else {
|
||||
eerror ("%s: unknown applet", applet);
|
||||
retval = EXIT_FAILURE;
|
||||
|
@ -237,9 +237,6 @@ static void cleanup (void)
|
||||
if (! rc_in_plugin && prefix_locked)
|
||||
unlink (PREFIX_LOCK);
|
||||
|
||||
/* Flush our buffered output if any */
|
||||
eclose ();
|
||||
|
||||
if (hook_out)
|
||||
rc_plugin_run (hook_out, applet);
|
||||
rc_plugin_unload ();
|
||||
@ -317,7 +314,7 @@ static int write_prefix (int fd, const char *buffer, size_t bytes, bool *prefixe
|
||||
ret += write (fd, ec, strlen (ec));
|
||||
ret += write (fd, prefix, strlen (prefix));
|
||||
ret += write (fd, ec_normal, strlen (ec_normal));
|
||||
ret += write (fd, "|", 2);
|
||||
ret += write (fd, "|", 1);
|
||||
*prefixed = true;
|
||||
}
|
||||
|
||||
@ -335,12 +332,8 @@ static bool svc_exec (const char *arg1, const char *arg2)
|
||||
int stdout_pipes[2];
|
||||
int stderr_pipes[2];
|
||||
|
||||
/* To ensure any output has hit our ebuffer */
|
||||
fflush (stdout);
|
||||
fflush (stderr);
|
||||
|
||||
/* Setup our pipes for prefixed output */
|
||||
if (rc_is_env ("RC_PREFIX", "yes")) {
|
||||
if (prefix) {
|
||||
if (pipe (stdout_pipes))
|
||||
eerror ("pipe: %s", strerror (errno));
|
||||
if (pipe (stderr_pipes))
|
||||
@ -356,7 +349,7 @@ static bool svc_exec (const char *arg1, const char *arg2)
|
||||
if (service_pid == -1)
|
||||
eerrorx ("%s: vfork: %s", service, strerror (errno));
|
||||
if (service_pid == 0) {
|
||||
if (rc_is_env ("RC_PREFIX", "yes")) {
|
||||
if (prefix) {
|
||||
int flags;
|
||||
|
||||
if (dup2 (stdout_pipes[1], fileno (stdout)) == -1)
|
||||
@ -391,7 +384,7 @@ static bool svc_exec (const char *arg1, const char *arg2)
|
||||
}
|
||||
|
||||
/* Prefix our piped output */
|
||||
if (rc_is_env ("RC_PREFIX", "yes")) {
|
||||
if (prefix) {
|
||||
bool stdout_done = false;
|
||||
bool stdout_prefix_shown = false;
|
||||
bool stderr_done = false;
|
||||
@ -958,9 +951,6 @@ static void svc_restart (bool deps)
|
||||
if (! rc_service_state (service, rc_service_stopped)) {
|
||||
get_started_services ();
|
||||
svc_stop (deps);
|
||||
|
||||
/* Flush our buffered output if any */
|
||||
eflush ();
|
||||
}
|
||||
|
||||
svc_start (deps);
|
||||
@ -1079,7 +1069,7 @@ int main (int argc, char **argv)
|
||||
setenv ("RC_RUNSCRIPT_PID", pid, 1);
|
||||
|
||||
/* eprefix is kinda klunky, but it works for our purposes */
|
||||
if (rc_is_env ("RC_PREFIX", "yes")) {
|
||||
if (rc_is_env ("RC_PARALLEL", "yes")) {
|
||||
int l = 0;
|
||||
int ll;
|
||||
|
||||
@ -1100,17 +1090,6 @@ int main (int argc, char **argv)
|
||||
eprefix (prefix);
|
||||
}
|
||||
|
||||
/* If we're in parallel and we're not prefixing then we need the ebuffer */
|
||||
if (rc_is_env ("RC_PARALLEL", "yes") && ! rc_is_env ("RC_PREFIX", "yes")) {
|
||||
char ebname[PATH_MAX];
|
||||
char *eb;
|
||||
|
||||
snprintf (ebname, sizeof (ebname), "%s.%s", applet, pid);
|
||||
eb = rc_strcatpaths (RC_SVCDIR "ebuffer", ebname, (char *) NULL);
|
||||
ebuffer (eb);
|
||||
free (eb);
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
/* Ok, we are ready to go, so setup selinux if applicable */
|
||||
setup_selinux (argc, argv);
|
||||
@ -1265,9 +1244,6 @@ int main (int argc, char **argv)
|
||||
} else
|
||||
svc_exec (optarg, NULL);
|
||||
|
||||
/* Flush our buffered output if any */
|
||||
eflush ();
|
||||
|
||||
/* We should ensure this list is empty after an action is done */
|
||||
rc_strlist_free (restart_services);
|
||||
restart_services = NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user