X-Git-Url: https://git.saurik.com/apple/launchd.git/blobdiff_plain/ed34e3c3e5fb80e0702ac7fb92f189862089d820..fe044cc98403cac59817868f8d7a614570993521:/launchd/src/launchd_unix_ipc.c diff --git a/launchd/src/launchd_unix_ipc.c b/launchd/src/launchd_unix_ipc.c index 712a124..c939c1f 100644 --- a/launchd/src/launchd_unix_ipc.c +++ b/launchd/src/launchd_unix_ipc.c @@ -18,7 +18,10 @@ * @APPLE_APACHE_LICENSE_HEADER_END@ */ -static const char *const __rcs_file_version__ = "$Revision: 1.11 $"; +static const char *const __rcs_file_version__ = "$Revision: 23274 $"; + +#include "config.h" +#include "launchd_unix_ipc.h" #include #include @@ -36,7 +39,6 @@ static const char *const __rcs_file_version__ = "$Revision: 1.11 $"; #include #include #include -#include #include #include #include @@ -45,15 +47,15 @@ static const char *const __rcs_file_version__ = "$Revision: 1.11 $"; #include #include -#include "launch.h" -#include "launch_priv.h" +#include "liblaunch_public.h" +#include "liblaunch_private.h" #include "launchd.h" +#include "launchd_runtime.h" #include "launchd_core_logic.h" -#include "launchd_unix_ipc.h" extern char **environ; -static SLIST_HEAD(, conncb) connections = { NULL }; +static LIST_HEAD(, conncb) connections; static launch_data_t adjust_rlimits(launch_data_t in); @@ -73,29 +75,28 @@ static bool ipc_inited = false; void ipc_clean_up(void) { - if (ipc_self != getpid()) + if (ipc_self != getpid()) { return; + } - if (-1 == unlink(sockpath)) - syslog(LOG_WARNING, "unlink(\"%s\"): %m", sockpath); - else if (-1 == rmdir(sockdir)) - syslog(LOG_WARNING, "rmdir(\"%s\"): %m", sockdir); + if (-1 == unlink(sockpath)) { + runtime_syslog(LOG_WARNING, "unlink(\"%s\"): %m", sockpath); + } else if (-1 == rmdir(sockdir)) { + runtime_syslog(LOG_WARNING, "rmdir(\"%s\"): %m", sockdir); + } } void -ipc_server_init(int *fds, size_t fd_cnt) +ipc_server_init(void) { struct sockaddr_un sun; mode_t oldmask; int r, fd = -1; char ourdir[1024]; - size_t i; - if (ipc_inited) + if (ipc_inited) { return; - - if (fds) - goto add_fds; + } memset(&sun, 0, sizeof(sun)); sun.sun_family = AF_UNIX; @@ -113,75 +114,69 @@ ipc_server_init(int *fds, size_t fd_cnt) stat(ourdir, &sb); if (!S_ISDIR(sb.st_mode)) { errno = EEXIST; - syslog(LOG_ERR, "mkdir(\"%s\"): %m", LAUNCHD_SOCK_PREFIX); + runtime_syslog(LOG_ERR, "mkdir(\"%s\"): %m", LAUNCHD_SOCK_PREFIX); goto out_bad; } } else { - syslog(LOG_ERR, "mkdir(\"%s\"): %m", ourdir); + runtime_syslog(LOG_ERR, "mkdir(\"%s\"): %m", ourdir); goto out_bad; } } } else { snprintf(ourdir, sizeof(ourdir), "/tmp/launchd-%u.XXXXXX", getpid()); - if (!launchd_assumes(mkdtemp(ourdir) != NULL)) + if (!launchd_assumes(mkdtemp(ourdir) != NULL)) { goto out_bad; + } snprintf(sun.sun_path, sizeof(sun.sun_path), "%s/sock", ourdir); - setenv(LAUNCHD_SOCKET_ENV, sun.sun_path, 1); } if (unlink(sun.sun_path) == -1 && errno != ENOENT) { - if (errno != EROFS) - syslog(LOG_ERR, "unlink(\"thesocket\"): %m"); + if (errno != EROFS) { + runtime_syslog(LOG_ERR, "unlink(\"thesocket\"): %m"); + } goto out_bad; } - if (!launchd_assumes((fd = _fd(socket(AF_UNIX, SOCK_STREAM, 0))) != -1)) + if (!launchd_assumes((fd = _fd(socket(AF_UNIX, SOCK_STREAM, 0))) != -1)) { goto out_bad; + } oldmask = umask(S_IRWXG|S_IRWXO); r = bind(fd, (struct sockaddr *)&sun, sizeof(sun)); umask(oldmask); if (r == -1) { - if (errno != EROFS) - syslog(LOG_ERR, "bind(\"thesocket\"): %m"); + if (errno != EROFS) { + runtime_syslog(LOG_ERR, "bind(\"thesocket\"): %m"); + } goto out_bad; } if (listen(fd, SOMAXCONN) == -1) { - syslog(LOG_ERR, "listen(\"thesocket\"): %m"); + runtime_syslog(LOG_ERR, "listen(\"thesocket\"): %m"); goto out_bad; } -add_fds: - if (fds) { - for (i = 0; i < fd_cnt; i++) { - if (kevent_mod(fds[i], EVFILT_READ, EV_ADD, 0, 0, &kqipc_listen_callback) == -1) { - syslog(LOG_ERR, "kevent_mod(%d, EVFILT_READ): %m", fds[i]); - goto out_bad; - } - } - } else if (kevent_mod(fd, EVFILT_READ, EV_ADD, 0, 0, &kqipc_listen_callback) == -1) { - syslog(LOG_ERR, "kevent_mod(\"thesocket\", EVFILT_READ): %m"); + if (kevent_mod(fd, EVFILT_READ, EV_ADD, 0, 0, &kqipc_listen_callback) == -1) { + runtime_syslog(LOG_ERR, "kevent_mod(\"thesocket\", EVFILT_READ): %m"); goto out_bad; } ipc_inited = true; - if (!fds) { - sockdir = strdup(ourdir); - sockpath = strdup(sun.sun_path); - ipc_self = getpid(); - atexit(ipc_clean_up); - } + sockdir = strdup(ourdir); + sockpath = strdup(sun.sun_path); + ipc_self = getpid(); + atexit(ipc_clean_up); out_bad: - if (!ipc_inited && fd != -1) - launchd_assumes(close(fd) == 0); + if (!ipc_inited && fd != -1) { + launchd_assumes(runtime_close(fd) == 0); + } } void -ipc_open(int fd, struct jobcb *j) +ipc_open(int fd, job_t j) { struct conncb *c = calloc(1, sizeof(struct conncb)); @@ -190,7 +185,7 @@ ipc_open(int fd, struct jobcb *j) c->kqconn_callback = ipc_callback; c->conn = launchd_fdopen(fd); c->j = j; - SLIST_INSERT_HEAD(&connections, c, sle); + LIST_INSERT_HEAD(&connections, c, sle); kevent_mod(fd, EVFILT_READ, EV_ADD, 0, 0, &c->kqconn_callback); } @@ -216,22 +211,23 @@ ipc_callback(void *obj, struct kevent *kev) if (kev->filter == EVFILT_READ) { if (launchd_msg_recv(c->conn, ipc_readmsg, c) == -1 && errno != EAGAIN) { - if (errno != ECONNRESET) - syslog(LOG_DEBUG, "%s(): recv: %m", __func__); + if (errno != ECONNRESET) { + runtime_syslog(LOG_DEBUG, "%s(): recv: %m", __func__); + } ipc_close(c); } } else if (kev->filter == EVFILT_WRITE) { r = launchd_msg_send(c->conn, NULL); if (r == -1) { if (errno != EAGAIN) { - syslog(LOG_DEBUG, "%s(): send: %m", __func__); + runtime_syslog(LOG_DEBUG, "%s(): send: %m", __func__); ipc_close(c); } } else if (r == 0) { kevent_mod(launchd_getfd(c->conn), EVFILT_WRITE, EV_DELETE, 0, 0, NULL); } } else { - syslog(LOG_DEBUG, "%s(): unknown filter type!", __func__); + runtime_syslog(LOG_DEBUG, "%s(): unknown filter type!", __func__); ipc_close(c); } } @@ -241,6 +237,18 @@ static void set_user_env(launch_data_t obj, const char *key, void *context __att setenv(key, launch_data_get_string(obj), 1); } +void +ipc_close_all_with_job(job_t j) +{ + struct conncb *ci, *cin; + + LIST_FOREACH_SAFE(ci, &connections, sle, cin) { + if (ci->j == j) { + ipc_close(ci); + } + } +} + void ipc_close_fds(launch_data_t o) { @@ -255,8 +263,9 @@ ipc_close_fds(launch_data_t o) ipc_close_fds(launch_data_array_get_index(o, i)); break; case LAUNCH_DATA_FD: - if (launch_data_get_fd(o) != -1) - launchd_assumes(close(launch_data_get_fd(o)) == 0); + if (launch_data_get_fd(o) != -1) { + launchd_assumes(runtime_close(launch_data_get_fd(o)) == 0); + } break; default: break; @@ -302,8 +311,9 @@ ipc_readmsg(launch_data_t msg, void *context) rmc.resp = launch_data_new_errno(EINVAL); } - if (NULL == rmc.resp) + if (NULL == rmc.resp) { rmc.resp = launch_data_new_errno(ENOSYS); + } ipc_close_fds(msg); @@ -311,7 +321,7 @@ ipc_readmsg(launch_data_t msg, void *context) if (errno == EAGAIN) { kevent_mod(launchd_getfd(rmc.c->conn), EVFILT_WRITE, EV_ADD, 0, 0, &rmc.c->kqconn_callback); } else { - syslog(LOG_DEBUG, "launchd_msg_send() == -1: %m"); + runtime_syslog(LOG_DEBUG, "launchd_msg_send() == -1: %m"); ipc_close(rmc.c); } } @@ -324,10 +334,13 @@ ipc_readmsg2(launch_data_t data, const char *cmd, void *context) { struct readmsg_context *rmc = context; launch_data_t resp = NULL; - struct jobcb *j; + job_t j; - if (rmc->resp) + if (rmc->resp) { return; + } + + //job_log(rmc->c->j, LOG_DEBUG, "Unix IPC request: %s", cmd); if (data == NULL) { if (!strcmp(cmd, LAUNCH_KEY_CHECKIN)) { @@ -337,9 +350,6 @@ ipc_readmsg2(launch_data_t data, const char *cmd, void *context) } else { resp = launch_data_new_errno(EACCES); } - } else if (!strcmp(cmd, LAUNCH_KEY_RELOADTTYS)) { - update_ttys(); - resp = launch_data_new_errno(0); } else if (!strcmp(cmd, LAUNCH_KEY_SHUTDOWN)) { launchd_shutdown(); resp = launch_data_new_errno(0); @@ -351,25 +361,6 @@ ipc_readmsg2(launch_data_t data, const char *cmd, void *context) ipc_revoke_fds(resp); } else if (!strcmp(cmd, LAUNCH_KEY_GETRESOURCELIMITS)) { resp = adjust_rlimits(NULL); - } else if (!strcmp(cmd, LAUNCH_KEY_GETUSERENVIRONMENT)) { - char **tmpenviron = environ; - resp = launch_data_alloc(LAUNCH_DATA_DICTIONARY); - for (; *tmpenviron; tmpenviron++) { - char envkey[1024]; - launch_data_t s = launch_data_alloc(LAUNCH_DATA_STRING); - launch_data_set_string(s, strchr(*tmpenviron, '=') + 1); - strncpy(envkey, *tmpenviron, sizeof(envkey)); - *(strchr(envkey, '=')) = '\0'; - launch_data_dict_insert(resp, s, envkey); - } - } else if (!strcmp(cmd, LAUNCH_KEY_GETLOGMASK)) { - int oldmask = setlogmask(LOG_UPTO(LOG_DEBUG)); - resp = launch_data_new_integer(oldmask); - setlogmask(oldmask); - } else if (!strcmp(cmd, LAUNCH_KEY_GETUMASK)) { - mode_t oldmask = umask(0); - resp = launch_data_new_integer(oldmask); - umask(oldmask); } else if (!strcmp(cmd, LAUNCH_KEY_GETRUSAGESELF)) { struct rusage rusage; getrusage(RUSAGE_SELF, &rusage); @@ -378,24 +369,21 @@ ipc_readmsg2(launch_data_t data, const char *cmd, void *context) struct rusage rusage; getrusage(RUSAGE_CHILDREN, &rusage); resp = launch_data_new_opaque(&rusage, sizeof(rusage)); - } else if (!strcmp(cmd, LAUNCH_KEY_BATCHQUERY)) { - resp = launch_data_alloc(LAUNCH_DATA_BOOL); - launch_data_set_bool(resp, batch_disabler_count == 0); } } else if (!strcmp(cmd, LAUNCH_KEY_STARTJOB)) { - if ((j = job_find(root_job, launch_data_get_string(data))) != NULL) { - job_start(j); + if ((j = job_find(launch_data_get_string(data))) != NULL) { + job_dispatch(j, true); errno = 0; } resp = launch_data_new_errno(errno); } else if (!strcmp(cmd, LAUNCH_KEY_STOPJOB)) { - if ((j = job_find(root_job, launch_data_get_string(data))) != NULL) { + if ((j = job_find(launch_data_get_string(data))) != NULL) { job_stop(j); errno = 0; } resp = launch_data_new_errno(errno); } else if (!strcmp(cmd, LAUNCH_KEY_REMOVEJOB)) { - if ((j = job_find(root_job, launch_data_get_string(data))) != NULL) { + if ((j = job_find(launch_data_get_string(data))) != NULL) { job_remove(j); errno = 0; } @@ -404,8 +392,9 @@ ipc_readmsg2(launch_data_t data, const char *cmd, void *context) if (launch_data_get_type(data) == LAUNCH_DATA_ARRAY) { resp = job_import_bulk(data); } else { - if (job_import(data)) + if (job_import(data)) { errno = 0; + } resp = launch_data_new_errno(errno); } } else if (!strcmp(cmd, LAUNCH_KEY_UNSETUSERENVIRONMENT)) { @@ -417,29 +406,12 @@ ipc_readmsg2(launch_data_t data, const char *cmd, void *context) } else if (!strcmp(cmd, LAUNCH_KEY_SETRESOURCELIMITS)) { resp = adjust_rlimits(data); } else if (!strcmp(cmd, LAUNCH_KEY_GETJOB)) { - if ((j = job_find(root_job, launch_data_get_string(data))) == NULL) { + if ((j = job_find(launch_data_get_string(data))) == NULL) { resp = launch_data_new_errno(errno); } else { resp = job_export(j); ipc_revoke_fds(resp); } - } else if (!strcmp(cmd, LAUNCH_KEY_GETJOBWITHHANDLES)) { - if ((j = job_find(root_job, launch_data_get_string(data))) == NULL) { - resp = launch_data_new_errno(errno); - } else { - resp = job_export(j); - } - } else if (!strcmp(cmd, LAUNCH_KEY_SETLOGMASK)) { - resp = launch_data_new_integer(setlogmask(launch_data_get_integer(data))); - } else if (!strcmp(cmd, LAUNCH_KEY_SETUMASK)) { - resp = launch_data_new_integer(umask(launch_data_get_integer(data))); - } else if (!strcmp(cmd, LAUNCH_KEY_SETSTDOUT)) { - resp = launchd_setstdio(STDOUT_FILENO, data); - } else if (!strcmp(cmd, LAUNCH_KEY_SETSTDERR)) { - resp = launchd_setstdio(STDERR_FILENO, data); - } else if (!strcmp(cmd, LAUNCH_KEY_BATCHCONTROL)) { - batch_job_enable(launch_data_get_bool(data), rmc->c); - resp = launch_data_new_errno(0); } rmc->resp = resp; @@ -448,10 +420,8 @@ ipc_readmsg2(launch_data_t data, const char *cmd, void *context) void ipc_close(struct conncb *c) { - batch_job_enable(true, c); - - SLIST_REMOVE(&connections, c, conncb, sle); - launchd_close(c->conn); + LIST_REMOVE(c, sle); + launchd_close(c->conn, runtime_close); free(c); } @@ -471,15 +441,16 @@ adjust_rlimits(launch_data_t in) ltmpsz = launch_data_get_opaque_size(in); if (ltmpsz > sizeof(l)) { - syslog(LOG_WARNING, "Too much rlimit data sent!"); + runtime_syslog(LOG_WARNING, "Too much rlimit data sent!"); ltmpsz = sizeof(l); } for (i = 0; i < (ltmpsz / sizeof(struct rlimit)); i++) { - if (ltmp[i].rlim_cur == l[i].rlim_cur && ltmp[i].rlim_max == l[i].rlim_max) + if (ltmp[i].rlim_cur == l[i].rlim_cur && ltmp[i].rlim_max == l[i].rlim_max) { continue; + } - if (/* XXX readcfg_pid && */ getpid() == 1) { + if (/* XXX readcfg_pid && */ getpid() == 1 && (i == RLIMIT_NOFILE || i == RLIMIT_NPROC)) { int gmib[] = { CTL_KERN, KERN_MAXPROC }; int pmib[] = { CTL_KERN, KERN_MAXPROCPERUID }; const char *gstr = "kern.maxproc"; @@ -495,8 +466,9 @@ adjust_rlimits(launch_data_t in) break; case RLIMIT_NPROC: /* kernel will not clamp to this value, we must */ - if (gval > (2048 + 20)) + if (gval > (2048 + 20)) { gval = 2048 + 20; + } break; default: break; @@ -505,12 +477,12 @@ adjust_rlimits(launch_data_t in) if (gval > 0) { launchd_assumes(sysctl(gmib, 2, NULL, NULL, &gval, sizeof(gval)) != -1); } else { - syslog(LOG_WARNING, "sysctl(\"%s\"): can't be zero", gstr); + runtime_syslog(LOG_WARNING, "sysctl(\"%s\"): can't be zero", gstr); } if (pval > 0) { launchd_assumes(sysctl(pmib, 2, NULL, NULL, &pval, sizeof(pval)) != -1); } else { - syslog(LOG_WARNING, "sysctl(\"%s\"): can't be zero", pstr); + runtime_syslog(LOG_WARNING, "sysctl(\"%s\"): can't be zero", pstr); } } launchd_assumes(setrlimit(i, ltmp + i) != -1);