]> git.saurik.com Git - apple/launchd.git/blobdiff - launchd/src/launchd_unix_ipc.c
launchd-258.1.tar.gz
[apple/launchd.git] / launchd / src / launchd_unix_ipc.c
index 712a12441b09795bea238f1601a8ef7151265e84..c939c1f3420e1b86ad2a3be53084e7ac87ead104 100644 (file)
  * @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 <sys/types.h>
 #include <sys/queue.h>
@@ -36,7 +39,6 @@ static const char *const __rcs_file_version__ = "$Revision: 1.11 $";
 #include <unistd.h>
 #include <signal.h>
 #include <errno.h>
-#include <syslog.h>
 #include <libgen.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -45,15 +47,15 @@ static const char *const __rcs_file_version__ = "$Revision: 1.11 $";
 #include <paths.h>
 #include <string.h>
 
-#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);