Browse files

wrapper: make errors fall through to exec()

Above the declaration of _vprocmgr_move_subset_to_user() in
10.8's launchd-442.21/liblaunch/vproc_priv.h there is a comment that
reads:

> One day, we'll be able to get rid of this...

This caused me to consider the situation where the function is no
longer available (whether or not some other workaround is required
to (e.g.) gain access to the pasteboard).

The original behavior of this wrapper program is to immediately
abort on all errors. This is acceptable behavior for programs that
are used interactively where the user can decide what to do next
(e.g. try again without the wrapper).

However, this wrapper is not typically used interactively, but more
"automatically" (e.g. via default-command in tmux; as I described in
the README). The abort-on-error behavior is much less acceptable in
this situation (it would appear that tmux was unable to create
(default) sessions, windows, or panes). For "automatic" uses, it
would be much nicer to always attempt to run the specified program
(after printing an appropriate message that describes the reason we
failed to reattach to the user bootstrap namespace).

Therefore, adjust the error handling so that we always fall through
to the code that does the exec() (while still issuing informative
messages).
  • Loading branch information...
1 parent 8f86025 commit 7420a3f817f57b7d2018869ba0b776a2c7a2b3d9 @ChrisJohnsen committed Aug 1, 2012
Showing with 35 additions and 12 deletions.
  1. +9 −0 msg.c
  2. +1 −0 msg.h
  3. +25 −12 reattach-to-user-namespace.c
View
9 msg.c
@@ -102,6 +102,15 @@ void warn(const char *fmt, ...) {
va_end(ap);
}
+void warn_errno(const char *fmt, ...) {
+ int err = errno; /* just in case it gets clobbered */
+ va_list ap;
+ va_start(ap, fmt);
+ vmsg("warning: ", strerror(err), fmt, ap);
+ va_end(ap);
+ errno = err;
+}
+
void die(int ev, const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
View
1 msg.h
@@ -39,5 +39,6 @@ extern FILE *msgout;
void vmsg(const char *pre, const char *suf, const char *fmt, va_list ap);
void msg(const char *fmt, ...);
void warn(const char *fmt, ...);
+void warn_errno(const char *fmt, ...);
void die(int ev, const char *fmt, ...);
void die_errno(int ev, const char *fmt, ...);
View
37 reattach-to-user-namespace.c
@@ -72,14 +72,20 @@ int main(int argc, char *argv[]) {
unsigned int os = 0;
struct utsname u;
- if (uname(&u))
- die_errno(2, "uname failed");
- if (strcmp(u.sysname, "Darwin"))
+ if (uname(&u)) {
+ warn_errno("uname failed");
+ goto reattach_failed;
+ }
+ if (strcmp(u.sysname, "Darwin")) {
warn("unsupported OS sysname: %s", u.sysname);
+ goto reattach_failed;
+ }
char *rest, *whole = strdup(u.release);
- if (!whole)
- die_errno(2, "strdup failed");
+ if (!whole) {
+ warn_errno("strdup failed");
+ goto reattach_failed;
+ }
rest = whole;
strsep(&rest, ".");
if (whole && *whole && whole != rest) {
@@ -121,8 +127,10 @@ int main(int argc, char *argv[]) {
{
static const char fn[] = "_vprocmgr_move_subset_to_user";
void *f;
- if (!(f = dlsym(RTLD_NEXT, fn)))
- die(2, "unable to find %s: %s", fn, dlerror());
+ if (!(f = dlsym(RTLD_NEXT, fn))) {
+ warn("unable to find %s: %s", fn, dlerror());
+ goto reattach_failed;
+ }
void *r;
static const char bg[] = "Background";
@@ -140,15 +148,20 @@ int main(int argc, char *argv[]) {
else if (os == 1060) {
void *(*func)(uid_t, const char *, uint64_t) = f;
r = func(getuid(), bg, 0);
- } else
- die(2, "BUG: unhandled reattach variation: %u", os);
+ } else {
+ warn("BUG: unhandled reattach variation: %u", os);
+ goto reattach_failed;
+ }
- if (r)
- die(2, "%s failed", fn);
+ if (r) {
+ warn("%s failed", fn);
+ goto reattach_failed;
+ }
}
break;
default:
- die(2, "unsupported OS, giving up");
+reattach_failed:
+ warn("unable to reattach");
break;
}

0 comments on commit 7420a3f

Please sign in to comment.