]> git.saurik.com Git - apple/launchd.git/commitdiff
launchd-106.10.tar.gz mac-os-x-1044x86 mac-os-x-1045x86 v106.10
authorApple <opensource@apple.com>
Mon, 20 Feb 2006 21:41:55 +0000 (21:41 +0000)
committerApple <opensource@apple.com>
Mon, 20 Feb 2006 21:41:55 +0000 (21:41 +0000)
15 files changed:
launchd/src/ConsoleMessage.c
launchd/src/IPC.c
launchd/src/StartupItems.c
launchd/src/bootstrap.c
launchd/src/launch.h
launchd/src/launchctl.c
launchd/src/launchd.c
launchd/src/launchd.plist.5
launchd/src/launchdebugd.c
launchd/src/launchproxy.c
launchd/src/liblaunch.c
launchd/src/lists.c
launchd/src/rc
launchd/src/register_mach_bootstrap_servers.c
launchd/src/wait4path.c

index a07f4ab113aa3108ab16bf648aa0ea831361d3c3..30f1cf67e162f6c6dd83d9872279e45915a50042 100644 (file)
@@ -235,7 +235,7 @@ static void     replyCallback(CFMachPortRef port __attribute__((unused)), void *
        if (aReply != NULL &&
            aMessage->aProtocol == kIPCProtocolVersion &&
            aMessage->aByteLength >= 0) {
-               *aReply = CFDataCreate(NULL, (char *) aMessage + aMessage->aByteLength, aMessage->aByteLength);
+               *aReply = CFDataCreate(NULL, (UInt8 *) aMessage + aMessage->aByteLength, aMessage->aByteLength);
        } else if (aReply != NULL) {
                *aReply = NULL;
        }
index b8e4dd61f9e9142604dc5b6772daf6b8980e307b..6c8e2aa89811f7fea1deee111fc9910ccaad06ac 100644 (file)
@@ -238,7 +238,7 @@ queryConfigSetting(StartupContext aStartupContext, CFDictionaryRef anIPCMessage)
                        }
                }
        }
-       return CFDataCreate(NULL, aValue, strlen(aValue) + 1);  /* aValue + null */
+       return CFDataCreate(NULL, (const UInt8 *)aValue, strlen(aValue) + 1);   /* aValue + null */
 }
 
 static void    *handleIPCMessage(void *aMsgParam, CFIndex aMessageSize __attribute__((unused)), CFAllocatorRef anAllocator __attribute__((unused)), void *aMachPort) {
@@ -313,7 +313,7 @@ static void    *handleIPCMessage(void *aMsgParam, CFIndex aMessageSize __attribu
          * Generate a Mach message for the result data.
          */
        if (!aResult)
-               aResult = CFDataCreateWithBytesNoCopy(NULL, "", 1, kCFAllocatorNull);
+               aResult = CFDataCreateWithBytesNoCopy(NULL, (const UInt8 *)"", 1, kCFAllocatorNull);
        if (aResult) {
                CFIndex         aDataSize = CFDataGetLength(aResult);
                CFIndex         aReplyMessageSize = round_msg(sizeof(SystemStarterIPCMessage) + aDataSize + 3);
@@ -365,7 +365,7 @@ CreateIPCRunLoopSource(CFStringRef aPortName, StartupContext aStartupContext)
        if (aMachPort && aPortName) {
                CFIndex         aPortNameLength = CFStringGetLength(aPortName);
                CFIndex         aPortNameSize = CFStringGetMaximumSizeForEncoding(aPortNameLength, kCFStringEncodingUTF8) + 1;
-               uint8_t        *aBuffer = CFAllocatorAllocate(NULL, aPortNameSize, 0);
+               char            *aBuffer = CFAllocatorAllocate(NULL, aPortNameSize, 0);
                if (aBuffer && CFStringGetCString(aPortName,
                                                  aBuffer,
                                                  aPortNameSize,
index 615cf60a1ae6041d483cf3a755e17934e8f42e60..3c95129e552eb757c9f57ebb08666b71ba4389a8 100644 (file)
@@ -356,7 +356,7 @@ StartupItemListCreateWithMask(NSSearchPathDomainMask aMask)
 
                                                                aConfigData =
                                                                        CFDataCreateWithBytesNoCopy(NULL,
-                                                                                                   aConfigFileContentsBuffer,
+                                                                                                   (const UInt8 *)aConfigFileContentsBuffer,
                                                                                                    aConfigFileContentsSize,
                                                                                                    kCFAllocatorNull);
 
index e309a31bf08973926a7e7745c9b1be207ec17761..82ef86ac37a26f8566ec47c921b37cc873ad65e9 100644 (file)
@@ -621,11 +621,37 @@ exec_server(server_t *serverp)
                                 serverp->cmd);
        }
 
-       if (serverp->uid != inherited_uid)
-               if (setuid(serverp->uid) < 0)
+       if (serverp->uid != inherited_uid) {
+               struct passwd *pwd = getpwuid(serverp->uid);
+               gid_t g;
+
+               if (NULL == pwd) {
+                       panic("Disabled server %x bootstrap %x: \"%s\": getpwuid(%d) failed",
+                                serverp->port, serverp->bootstrap->bootstrap_port,
+                                serverp->cmd, serverp->uid);
+               }
+
+               g = pwd->pw_gid;
+
+               if (-1 == setgroups(1, &g)) {
+                       panic("Disabled server %x bootstrap %x: \"%s\": setgroups(1, %d): %s",
+                                       serverp->port, serverp->bootstrap->bootstrap_port,
+                                       serverp->cmd, g, strerror(errno));
+               }
+
+               if (-1 == setgid(g)) {
+                       panic("Disabled server %x bootstrap %x: \"%s\": setgid(%d): %s",
+                                       serverp->port, serverp->bootstrap->bootstrap_port,
+                                       serverp->cmd, g, strerror(errno));
+               }
+
+               if (-1 == setuid(serverp->uid)) {
                        panic("Disabled server %x bootstrap %x: \"%s\": setuid(%d): %s",
                                         serverp->port, serverp->bootstrap->bootstrap_port,
                                           serverp->cmd, serverp->uid, strerror(errno));
+               }
+       }
+
 
        if (setsid() < 0) {
                /*
index 0a8a1750928ce8f62412b063866c4b9c741f8f6e..1d93ad954874d2abbf65c3f7f86dd1e4c42dd9ff 100644 (file)
@@ -94,6 +94,7 @@
 #define LAUNCH_JOBSOCKETKEY_BONJOUR            "Bonjour"
 #define LAUNCH_JOBSOCKETKEY_SECUREWITHKEY      "SecureSocketWithKey"
 #define LAUNCH_JOBSOCKETKEY_PATHNAME           "SockPathName"
+#define LAUNCH_JOBSOCKETKEY_PATHMODE           "SockPathMode"
 #define LAUNCH_JOBSOCKETKEY_NODENAME           "SockNodeName"
 #define LAUNCH_JOBSOCKETKEY_SERVICENAME                "SockServiceName"
 #define LAUNCH_JOBSOCKETKEY_FAMILY             "SockFamily"
index 5142250a8a2da0bd49083c88127590d12aa91b46..a0a405cc13e210da493f3c9560bcdf99f7e8893a 100644 (file)
@@ -21,6 +21,8 @@
  * @APPLE_LICENSE_HEADER_END@
  */
 #include <CoreFoundation/CoreFoundation.h>
+#include <mach/mach.h>
+#include <servers/bootstrap.h>
 #include <sys/types.h>
 #include <sys/time.h>
 #include <sys/stat.h>
 
 #define LAUNCH_SECDIR "/tmp/launch-XXXXXX"
 
+#define MACHINIT_JOBKEY_ONDEMAND       "OnDemand"
+#define MACHINIT_JOBKEY_SERVICENAME    "ServiceName"
+#define MACHINIT_JOBKEY_COMMAND                "Command"
+#define MACHINIT_JOBKEY_ISKUNCSERVER   "isKUNCServer"
+
+
+static void myCFDictionaryApplyFunction(const void *key, const void *value, void *context);
 static bool launch_data_array_append(launch_data_t a, launch_data_t o);
+static void distill_jobs(launch_data_t);
 static void distill_config_file(launch_data_t);
 static void sock_dict_cb(launch_data_t what, const char *key, void *context);
 static void sock_dict_edit_entry(launch_data_t tmp, const char *key, launch_data_t fdarray, launch_data_t thejob);
@@ -58,12 +68,19 @@ static launch_data_t CF2launch_data(CFTypeRef);
 static launch_data_t read_plist_file(const char *file, bool editondisk, bool load);
 static CFPropertyListRef CreateMyPropertyListFromFile(const char *);
 static void WriteMyPropertyListToFile(CFPropertyListRef, const char *);
-static void readpath(const char *, launch_data_t, launch_data_t, bool editondisk, bool load, bool forceload);
+static void readpath(const char *, launch_data_t, launch_data_t, launch_data_t, bool editondisk, bool load, bool forceload);
+static void readfile(const char *, launch_data_t, launch_data_t, launch_data_t, bool editondisk, bool load, bool forceload);
 static int _fd(int);
 static int demux_cmd(int argc, char *const argv[]);
 static launch_data_t do_rendezvous_magic(const struct addrinfo *res, const char *serv);
 static void submit_job_pass(launch_data_t jobs);
+static void submit_mach_jobs(launch_data_t jobs);
+static void let_go_of_mach_jobs(void);
 static void do_mgroup_join(int fd, int family, int socktype, int protocol, const char *mgroup);
+static void print_jobs(launch_data_t j, const char *label, void *context);
+static bool is_legacy_mach_job(launch_data_t obj);
+static bool delay_to_second_pass(launch_data_t o);
+static void delay_to_second_pass2(launch_data_t o, const char *key, void *context);
 
 static int load_and_unload_cmd(int argc, char *const argv[]);
 //static int reload_cmd(int argc, char *const argv[]);
@@ -216,21 +233,29 @@ static int setenv_cmd(int argc, char *const argv[])
        return 0;
 }
 
+static void print_launchd_env(launch_data_t obj, const char *key, void *context)
+{
+       bool *is_csh = context;
+
+       if (*is_csh)
+               fprintf(stdout, "setenv %s %s;\n", key, launch_data_get_string(obj));
+       else
+               fprintf(stdout, "%s=%s; export %s;\n", key, launch_data_get_string(obj), key);
+}
+
+static void print_key_value(launch_data_t obj, const char *key, void *context)
+{
+       const char *k = context;
+
+       if (!strcmp(key, k))
+               fprintf(stdout, "%s\n", launch_data_get_string(obj));
+}
+
 static int getenv_and_export_cmd(int argc, char *const argv[] __attribute__((unused)))
 {
        launch_data_t resp, msg;
        bool is_csh = false;
-       const char *k;
-       void print_launchd_env(launch_data_t obj, const char *key, void *context __attribute__((unused))) {
-               if (is_csh)
-                       fprintf(stdout, "setenv %s %s;\n", key, launch_data_get_string(obj));
-               else
-                       fprintf(stdout, "%s=%s; export %s;\n", key, launch_data_get_string(obj), key);
-       }
-       void print_key_value(launch_data_t obj, const char *key, void *context __attribute__((unused))) {
-               if (!strcmp(key, k))
-                       fprintf(stdout, "%s\n", launch_data_get_string(obj));
-       }
+       char *k;
        
        if (!strcmp(argv[0], "export")) {
                char *s = getenv("SHELL");
@@ -249,7 +274,10 @@ static int getenv_and_export_cmd(int argc, char *const argv[] __attribute__((unu
        launch_data_free(msg);
 
        if (resp) {
-               launch_data_dict_iterate(resp, (!strcmp(argv[0], "export")) ? print_launchd_env : print_key_value, NULL);
+               if (!strcmp(argv[0], "export"))
+                       launch_data_dict_iterate(resp, print_launchd_env, &is_csh);
+               else
+                       launch_data_dict_iterate(resp, print_key_value, k);
                launch_data_free(resp);
        } else {
                fprintf(stderr, "launch_msg(\"" LAUNCH_KEY_GETUSERENVIRONMENT "\"): %s\n", strerror(errno));
@@ -286,7 +314,8 @@ static void unloadjob(launch_data_t job)
        launch_data_free(resp);
 }
 
-static launch_data_t read_plist_file(const char *file, bool editondisk, bool load)
+launch_data_t
+read_plist_file(const char *file, bool editondisk, bool load)
 {
        CFPropertyListRef plist = CreateMyPropertyListFromFile(file);
        launch_data_t r = NULL;
@@ -311,7 +340,8 @@ static launch_data_t read_plist_file(const char *file, bool editondisk, bool loa
        return r;
 }
 
-static void delay_to_second_pass2(launch_data_t o, const char *key, void *context)
+void
+delay_to_second_pass2(launch_data_t o, const char *key, void *context)
 {
        bool *res = context;
        size_t i;
@@ -334,7 +364,8 @@ static void delay_to_second_pass2(launch_data_t o, const char *key, void *contex
        }
 }
 
-static bool delay_to_second_pass(launch_data_t o)
+bool
+delay_to_second_pass(launch_data_t o)
 {
        bool res = false;
 
@@ -348,7 +379,8 @@ static bool delay_to_second_pass(launch_data_t o)
        return res;
 }
 
-static void readfile(const char *what, launch_data_t pass1, launch_data_t pass2, bool editondisk, bool load, bool forceload)
+void
+readfile(const char *what, launch_data_t pass0, launch_data_t pass1, launch_data_t pass2, bool editondisk, bool load, bool forceload)
 {
        launch_data_t tmpd, thejob;
        bool job_disabled = false;
@@ -358,6 +390,11 @@ static void readfile(const char *what, launch_data_t pass1, launch_data_t pass2,
                return;
        }
 
+       if (is_legacy_mach_job(thejob)) {
+               launch_data_array_append(pass0, thejob);
+               return;
+       }
+
        if (NULL == launch_data_dict_lookup(thejob, LAUNCH_JOBKEY_LABEL)) {
                fprintf(stderr, "%s: missing the Label key: %s\n", getprogname(), what);
                launch_data_free(thejob);
@@ -381,7 +418,8 @@ static void readfile(const char *what, launch_data_t pass1, launch_data_t pass2,
                launch_data_array_append(pass1, thejob);
 }
 
-static void readpath(const char *what, launch_data_t pass1, launch_data_t pass2, bool editondisk, bool load, bool forceload)
+void
+readpath(const char *what, launch_data_t pass0, launch_data_t pass1, launch_data_t pass2, bool editondisk, bool load, bool forceload)
 {
        char buf[MAXPATHLEN];
        struct stat sb;
@@ -392,7 +430,7 @@ static void readpath(const char *what, launch_data_t pass1, launch_data_t pass2,
                return;
 
        if (S_ISREG(sb.st_mode) && !(sb.st_mode & S_IWOTH)) {
-               readfile(what, pass1, pass2, editondisk, load, forceload);
+               readfile(what, pass0, pass1, pass2, editondisk, load, forceload);
        } else {
                if ((d = opendir(what)) == NULL) {
                        fprintf(stderr, "%s: opendir() failed to open the directory\n", getprogname());
@@ -404,7 +442,7 @@ static void readpath(const char *what, launch_data_t pass1, launch_data_t pass2,
                                continue;
                        snprintf(buf, sizeof(buf), "%s/%s", what, de->d_name);
 
-                       readfile(buf, pass1, pass2, editondisk, load, forceload);
+                       readfile(buf, pass0, pass1, pass2, editondisk, load, forceload);
                }
                closedir(d);
        }
@@ -415,7 +453,17 @@ struct distill_context {
        launch_data_t newsockdict;
 };
 
-static void distill_config_file(launch_data_t id_plist)
+void
+distill_jobs(launch_data_t jobs)
+{
+       size_t i, c = launch_data_array_get_count(jobs);
+
+       for (i = 0; i < c; i++)
+               distill_config_file(launch_data_array_get_index(jobs, i));
+}
+
+void
+distill_config_file(launch_data_t id_plist)
 {
        struct distill_context dc = { id_plist, NULL };
        launch_data_t tmp;
@@ -487,6 +535,9 @@ static void sock_dict_edit_entry(launch_data_t tmp, const char *key, launch_data
                
        if ((val = launch_data_dict_lookup(tmp, LAUNCH_JOBSOCKETKEY_PATHNAME))) {
                struct sockaddr_un sun;
+               mode_t sun_mode = 0;
+               mode_t oldmask;
+               bool setm = false;
 
                memset(&sun, 0, sizeof(sun));
 
@@ -497,15 +548,26 @@ static void sock_dict_edit_entry(launch_data_t tmp, const char *key, launch_data
                if ((sfd = _fd(socket(AF_UNIX, st, 0))) == -1)
                        return;
 
+               if ((val = launch_data_dict_lookup(tmp, LAUNCH_JOBSOCKETKEY_PATHMODE))) {
+                       sun_mode = (mode_t)launch_data_get_integer(val);
+                       setm = true;
+               }
+
                if (passive) {                  
                        if (unlink(sun.sun_path) == -1 && errno != ENOENT) {
                                close(sfd);     
                                return;
                        }
+                       oldmask = umask(S_IRWXG|S_IRWXO);
                        if (bind(sfd, (struct sockaddr *)&sun, sizeof(sun)) == -1) {
                                close(sfd);
+                               umask(oldmask);
                                return;
                        }
+                       umask(oldmask);
+                       if (setm) {
+                               chmod(sun.sun_path, sun_mode);
+                       }
                        if ((st == SOCK_STREAM || st == SOCK_SEQPACKET)
                                        && listen(sfd, SOMAXCONN) == -1) {
                                close(sfd);
@@ -732,7 +794,7 @@ static CFPropertyListRef CreateMyPropertyListFromFile(const char *posixfile)
        SInt32            errorCode;
        CFURLRef          fileURL;
 
-       fileURL = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, posixfile, strlen(posixfile), false);
+       fileURL = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (const UInt8 *)posixfile, strlen(posixfile), false);
        if (!fileURL)
                fprintf(stderr, "%s: CFURLCreateFromFileSystemRepresentation(%s) failed\n", getprogname(), posixfile);
        if (!CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault, fileURL, &resourceData, NULL, NULL, &errorCode))
@@ -750,7 +812,7 @@ static void WriteMyPropertyListToFile(CFPropertyListRef plist, const char *posix
        CFURLRef        fileURL;
        SInt32          errorCode;
 
-       fileURL = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, posixfile, strlen(posixfile), false);
+       fileURL = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (const UInt8 *)posixfile, strlen(posixfile), false);
        if (!fileURL)
                fprintf(stderr, "%s: CFURLCreateFromFileSystemRepresentation(%s) failed\n", getprogname(), posixfile);
        resourceData = CFPropertyListCreateXMLData(kCFAllocatorDefault, plist);
@@ -866,7 +928,7 @@ static int _fd(int fd)
 
 static int load_and_unload_cmd(int argc, char *const argv[])
 {
-       launch_data_t pass1, pass2;
+       launch_data_t pass0, pass1, pass2;
        int i, ch;
        bool wflag = false;
        bool lflag = false;
@@ -892,7 +954,8 @@ static int load_and_unload_cmd(int argc, char *const argv[])
                return 1;
        }
 
-       /* I wish I didn't need to do two passes, but I need to load mDNSResponder and use it too.
+       /* I wish I didn't need to do three passes, but I need to load mDNSResponder and use it too.
+        * And loading legacy mach init jobs is extra fun.
         *
         * In later versions of launchd, I hope to load everything in the first pass,
         * then do the Bonjour magic on the jobs that need it, and reload them, but for now,
@@ -900,26 +963,30 @@ static int load_and_unload_cmd(int argc, char *const argv[])
         * launchd doesn't have reload support right now.
         */
 
+       pass0 = launch_data_alloc(LAUNCH_DATA_ARRAY);
        pass1 = launch_data_alloc(LAUNCH_DATA_ARRAY);
        pass2 = launch_data_alloc(LAUNCH_DATA_ARRAY);
 
        for (i = 0; i < argc; i++)
-               readpath(argv[i], pass1, pass2, wflag, lflag, Fflag);
+               readpath(argv[i], pass0, pass1, pass2, wflag, lflag, Fflag);
 
-       if (0 == launch_data_array_get_count(pass1) && 0 == launch_data_array_get_count(pass2)) {
+       if (launch_data_array_get_count(pass0) == 0 &&
+                       launch_data_array_get_count(pass1) == 0 &&
+                       launch_data_array_get_count(pass2) == 0) {
                fprintf(stderr, "nothing found to %s\n", lflag ? "load" : "unload");
+               launch_data_free(pass0);
                launch_data_free(pass1);
                launch_data_free(pass2);
                return 1;
        }
        
        if (lflag) {
-               if (0 < launch_data_array_get_count(pass1)) {
-                       submit_job_pass(pass1);
-               }
-               if (0 < launch_data_array_get_count(pass2)) {
-                       submit_job_pass(pass2);
-               }
+               distill_jobs(pass1);
+               submit_mach_jobs(pass0);
+               submit_job_pass(pass1);
+               let_go_of_mach_jobs();
+               distill_jobs(pass2);
+               submit_job_pass(pass2);
        } else {
                for (i = 0; i < (int)launch_data_array_get_count(pass1); i++)
                        unloadjob(launch_data_array_get_index(pass1, i));
@@ -930,14 +997,74 @@ static int load_and_unload_cmd(int argc, char *const argv[])
        return 0;
 }
 
-static void submit_job_pass(launch_data_t jobs)
+static mach_port_t *msrvs = NULL;
+static size_t msrvs_cnt = 0;
+
+void
+submit_mach_jobs(launch_data_t jobs)
+{
+       size_t i, c;
+
+       c = launch_data_array_get_count(jobs);
+
+       msrvs = calloc(1, sizeof(mach_port_t) * c);
+       msrvs_cnt = c;
+
+       for (i = 0; i < c; i++) {
+               launch_data_t tmp, oai = launch_data_array_get_index(jobs, i);
+               const char *sn = NULL, *cmd = NULL;
+               bool d = true, k = false;
+               mach_port_t msr, msv, mhp;
+               kern_return_t kr;
+               uid_t u = getuid();
+
+               if ((tmp = launch_data_dict_lookup(oai, MACHINIT_JOBKEY_ONDEMAND)))
+                       d = launch_data_get_bool(tmp);
+               if ((tmp = launch_data_dict_lookup(oai, MACHINIT_JOBKEY_ISKUNCSERVER)))
+                       k = launch_data_get_bool(tmp);
+               if ((tmp = launch_data_dict_lookup(oai, MACHINIT_JOBKEY_SERVICENAME)))
+                       sn = launch_data_get_string(tmp);
+               if ((tmp = launch_data_dict_lookup(oai, MACHINIT_JOBKEY_COMMAND)))
+                       cmd = launch_data_get_string(tmp);
+
+               if ((kr = bootstrap_create_server(bootstrap_port, (char *)cmd, u, d, &msr)) != KERN_SUCCESS) {
+                       fprintf(stderr, "%s: bootstrap_create_server(): %d\n", getprogname(), kr);
+                       continue;
+               }
+               if ((kr = bootstrap_create_service(msr, (char*)sn, &msv)) != KERN_SUCCESS) {
+                       fprintf(stderr, "%s: bootstrap_create_service(): %d\n", getprogname(), kr);
+                       mach_port_destroy(mach_task_self(), msr);
+                       continue;
+               }
+               if (k) {
+                       mhp = mach_host_self();
+                       if ((kr = host_set_UNDServer(mhp, msv)) != KERN_SUCCESS)
+                               fprintf(stderr, "%s: host_set_UNDServer(): %s\n", getprogname(), mach_error_string(kr));
+                       mach_port_deallocate(mach_task_self(), mhp);
+               }
+               mach_port_deallocate(mach_task_self(), msv);
+               msrvs[i] = msr;
+       }
+}
+
+void
+let_go_of_mach_jobs(void)
+{
+       size_t i;
+
+       for (i = 0; i < msrvs_cnt; i++)
+               mach_port_destroy(mach_task_self(), msrvs[i]);
+}
+
+void
+submit_job_pass(launch_data_t jobs)
 {
        launch_data_t msg, resp;
        size_t i;
        int e;
 
-       for (i = 0; i < launch_data_array_get_count(jobs); i++)
-               distill_config_file(launch_data_array_get_index(jobs, i));
+       if (launch_data_array_get_count(jobs) == 0)
+               return;
 
        msg = launch_data_alloc(LAUNCH_DATA_DICTIONARY);
 
@@ -1262,6 +1389,68 @@ static int logupdate_cmd(int argc, char *const argv[])
        return r;
 }
 
+static const struct {
+       const char *name;
+       int lim;
+} limlookup[] = {
+       { "cpu",        RLIMIT_CPU },
+       { "filesize",   RLIMIT_FSIZE },
+       { "data",       RLIMIT_DATA },
+       { "stack",      RLIMIT_STACK },
+       { "core",       RLIMIT_CORE },
+       { "rss",        RLIMIT_RSS },
+       { "memlock",    RLIMIT_MEMLOCK },
+       { "maxproc",    RLIMIT_NPROC },
+       { "maxfiles",   RLIMIT_NOFILE }
+};
+
+static const size_t limlookupcnt = sizeof limlookup / sizeof limlookup[0];
+
+static ssize_t name2num(const char *n)
+{
+       size_t i;
+
+       for (i = 0; i < limlookupcnt; i++) {
+               if (!strcmp(limlookup[i].name, n)) {
+                       return limlookup[i].lim;
+               }
+       }
+       return -1;
+}
+
+static const char *num2name(int n)
+{
+       size_t i;
+
+       for (i = 0; i < limlookupcnt; i++) {
+               if (limlookup[i].lim == n)
+                       return limlookup[i].name;
+       }
+       return NULL;
+}
+
+static const char *lim2str(rlim_t val, char *buf)
+{
+       if (val == RLIM_INFINITY)
+               strcpy(buf, "unlimited");
+       else
+               sprintf(buf, "%lld", val);
+       return buf;
+}
+
+static bool str2lim(const char *buf, rlim_t *res)
+{
+       char *endptr;
+       *res = strtoll(buf, &endptr, 10);
+       if (!strcmp(buf, "unlimited")) {
+               *res = RLIM_INFINITY;
+               return false;
+       } else if (*endptr == '\0') {
+                return false;
+       }
+       return true;
+}
+
 static int limit_cmd(int argc __attribute__((unused)), char *const argv[])
 {
        char slimstr[100];
@@ -1269,58 +1458,10 @@ static int limit_cmd(int argc __attribute__((unused)), char *const argv[])
        struct rlimit *lmts = NULL;
        launch_data_t resp, resp1 = NULL, msg, tmp;
        int r = 0;
-       size_t i, lsz = -1, which = 0;
+       size_t i, lsz = -1;
+       ssize_t which = 0;
        rlim_t slim = -1, hlim = -1;
        bool badargs = false;
-       static const struct {
-               const char *name;
-               int lim;
-       } limlookup[] = {
-               { "cpu",        RLIMIT_CPU },
-               { "filesize",   RLIMIT_FSIZE },
-               { "data",       RLIMIT_DATA },
-               { "stack",      RLIMIT_STACK },
-               { "core",       RLIMIT_CORE },
-               { "rss",        RLIMIT_RSS },
-               { "memlock",    RLIMIT_MEMLOCK },
-               { "maxproc",    RLIMIT_NPROC },
-               { "maxfiles",   RLIMIT_NOFILE }
-       };
-       size_t limlookupcnt = sizeof limlookup / sizeof limlookup[0];
-       bool name2num(const char *n) {
-               for (i = 0; i < limlookupcnt; i++) {
-                       if (!strcmp(limlookup[i].name, n)) {
-                               which = limlookup[i].lim;
-                               return false;
-                       }
-               }
-               return true;
-       };
-       const char *num2name(int n) {
-               for (i = 0; i < limlookupcnt; i++) {
-                       if (limlookup[i].lim == n)
-                               return limlookup[i].name;
-               }
-               return NULL;
-       };
-       const char *lim2str(rlim_t val, char *buf) {
-               if (val == RLIM_INFINITY)
-                       strcpy(buf, "unlimited");
-               else
-                       sprintf(buf, "%lld", val);
-               return buf;
-       };
-       bool str2lim(const char *buf, rlim_t *res) {
-               char *endptr;
-               *res = strtoll(buf, &endptr, 10);
-               if (!strcmp(buf, "unlimited")) {
-                       *res = RLIM_INFINITY;
-                       return false;
-               } else if (*endptr == '\0') {
-                        return false;
-               }
-               return true;
-       };
 
        if (argc > 4)
                badargs = true;
@@ -1333,7 +1474,7 @@ static int limit_cmd(int argc __attribute__((unused)), char *const argv[])
        if (argc == 4 && str2lim(argv[3], &hlim))
                badargs = true;
 
-       if (argc >= 2 && name2num(argv[1]))
+       if (argc >= 2 && -1 == (which = name2num(argv[1])))
                badargs = true;
 
        if (badargs) {
@@ -1356,7 +1497,7 @@ static int limit_cmd(int argc __attribute__((unused)), char *const argv[])
                lsz = launch_data_get_opaque_size(resp);
                if (argc <= 2) {
                        for (i = 0; i < (lsz / sizeof(struct rlimit)); i++) {
-                               if (argc == 2 && which != i)
+                               if (argc == 2 && (size_t)which != i)
                                        continue;
                                fprintf(stdout, "\t%-12s%-15s%-15s\n", num2name(i),
                                                lim2str(lmts[i].rlim_cur, slimstr),
@@ -1518,3 +1659,13 @@ static bool launch_data_array_append(launch_data_t a, launch_data_t o)
 
        return launch_data_array_set_index(a, o, offt);
 }
+
+bool
+is_legacy_mach_job(launch_data_t obj)
+{
+       bool has_servicename = launch_data_dict_lookup(obj, MACHINIT_JOBKEY_SERVICENAME);
+       bool has_command  = launch_data_dict_lookup(obj, MACHINIT_JOBKEY_COMMAND);
+       bool has_label = launch_data_dict_lookup(obj, LAUNCH_JOBKEY_LABEL);
+
+       return has_command && has_servicename && !has_label;
+}
index 0eb441be4f007973be8354426122371a406935cb..d6c1057e49b787adb5e427108aaa9913bd5613e6 100644 (file)
@@ -171,6 +171,7 @@ static void loopback_setup(void);
 static void workaround3048875(int argc, char *argv[]);
 static void reload_launchd_config(void);
 static int dir_has_files(const char *path);
+static void testfd_or_openfd(int fd, const char *path, int flags);
 static void setup_job_env(launch_data_t obj, const char *key, void *context);
 static void unsetup_job_env(launch_data_t obj, const char *key, void *context);
 
@@ -192,20 +193,6 @@ int main(int argc, char *argv[])
                SIGTERM, SIGURG, SIGTSTP, SIGTSTP, SIGCONT, /*SIGCHLD,*/
                SIGTTIN, SIGTTOU, SIGIO, SIGXCPU, SIGXFSZ, SIGVTALRM, SIGPROF,
                SIGWINCH, SIGINFO, SIGUSR1, SIGUSR2 };
-       void testfd_or_openfd(int fd, const char *path, int flags) {
-               int tmpfd;
-
-               if (-1 != (tmpfd = dup(fd))) {
-                       close(tmpfd);
-               } else {
-                       if (-1 == (tmpfd = open(path, flags))) {
-                               syslog(LOG_ERR, "open(\"%s\", ...): %m", path);
-                       } else if (tmpfd != fd) {
-                               dup2(tmpfd, fd);
-                               close(tmpfd);
-                       }
-               }
-       };
        struct kevent kev;
        size_t i;
        bool sflag = false, xflag = false, vflag = false, dflag = false;
@@ -333,11 +320,26 @@ static void pid1_magic_init(bool sflag, bool vflag, bool xflag)
        int memmib[2] = { CTL_HW, HW_PHYSMEM };
        int mvnmib[2] = { CTL_KERN, KERN_MAXVNODES };
        int hnmib[2] = { CTL_KERN, KERN_HOSTNAME };
+       int tfp_r_mib[3] = { CTL_KERN, KERN_TFP, KERN_TFP_READ_GROUP };
+       int tfp_rw_mib[3] = { CTL_KERN, KERN_TFP, KERN_TFP_RW_GROUP };
+       gid_t tfp_r_gid = 0;
+       gid_t tfp_rw_gid = 0;
+       struct group *tfp_gr;
        uint64_t mem = 0;
        uint32_t mvn;
        size_t memsz = sizeof(mem);
        int pthr_r;
-               
+
+       if ((tfp_gr = getgrnam("procview"))) {
+               tfp_r_gid = tfp_gr->gr_gid;
+               sysctl(tfp_r_mib, 3, NULL, NULL, &tfp_r_gid, sizeof(tfp_r_gid));
+       }
+
+       if ((tfp_gr = getgrnam("procmod"))) {
+               tfp_rw_gid = tfp_gr->gr_gid;
+               sysctl(tfp_rw_mib, 3, NULL, NULL, &tfp_rw_gid, sizeof(tfp_rw_gid));
+       }
+
        setpriority(PRIO_PROCESS, 0, -1);
 
        if (setsid() == -1)
@@ -2400,3 +2402,19 @@ static void async_callback(void)
                syslog(LOG_DEBUG, "unexpected: kevent() returned something != 0, -1 or 1");
        }
 }
+
+static void testfd_or_openfd(int fd, const char *path, int flags)
+{
+       int tmpfd;
+
+       if (-1 != (tmpfd = dup(fd))) {
+               close(tmpfd);
+       } else {
+               if (-1 == (tmpfd = open(path, flags))) {
+                       syslog(LOG_ERR, "open(\"%s\", ...): %m", path);
+               } else if (tmpfd != fd) {
+                       dup2(tmpfd, fd);
+                       close(tmpfd);
+               }
+       }
+}
index e9ab97af9422ee2617e4b34acd4adbddba615685..f6c1f2df23c2b95b33100eadda76358fb3f04bfe 100644 (file)
@@ -264,6 +264,8 @@ This optional key implies SockFamily is set to "Unix". It specifies the path to
 or
 .Xr bind 2
 to.
+.It Sy SockPathMode <integer>
+This optional key specifies the mode of the socket. Known bug: Property lists don't support octal, so please convert the value to decimal.
 .It Sy Bonjour <boolean or string or array of strings>
 This optional key can be used to request that the service be registered with the
 .Xr mDNSResponder 8 .
index 7d746c45cb7090c30be45edbe3aa663c48976113..3c3d238522c1b7460dabf431de4995a5d3216f3f 100644 (file)
@@ -123,25 +123,29 @@ int main(void)
        exit(EXIT_SUCCESS);
 }
 
+static void launch_print_obj_dict_callback(launch_data_t obj, const char *key, void *context)
+{
+       FILE *w = context;
+
+       fprintf(w, "<i>%s</i>\n", key);
+       if (launch_data_get_type(obj) != LAUNCH_DATA_ARRAY &&
+                       launch_data_get_type(obj) != LAUNCH_DATA_DICTIONARY)
+               fprintf(w, "<ul><li>\n");
+       launch_print_obj(obj, w);
+       if (launch_data_get_type(obj) != LAUNCH_DATA_ARRAY &&
+                       launch_data_get_type(obj) != LAUNCH_DATA_DICTIONARY)
+               fprintf(w, "</li></ul>\n");
+}
+
 static void launch_print_obj(launch_data_t o, FILE *w)
 {
        size_t i;
-       void launch_print_obj_dict_callback(launch_data_t obj, const char *key, void *context __attribute__((unused))) {
-               fprintf(w, "<i>%s</i>\n", key);
-               if (launch_data_get_type(obj) != LAUNCH_DATA_ARRAY &&
-                               launch_data_get_type(obj) != LAUNCH_DATA_DICTIONARY)
-                       fprintf(w, "<ul><li>\n");
-               launch_print_obj(obj, w);
-               if (launch_data_get_type(obj) != LAUNCH_DATA_ARRAY &&
-                               launch_data_get_type(obj) != LAUNCH_DATA_DICTIONARY)
-                       fprintf(w, "</li></ul>\n");
-       }
 
 
         switch (launch_data_get_type(o)) {
         case LAUNCH_DATA_DICTIONARY:
                fprintf(w, "<ul><li>\n");
-               launch_data_dict_iterate(o, launch_print_obj_dict_callback, NULL);
+               launch_data_dict_iterate(o, launch_print_obj_dict_callback, w);
                fprintf(w, "</li></ul>\n");
                 break;
         case LAUNCH_DATA_ARRAY:
index 481c8eb6149d63a36b462fd9822782f86852c797..6ab5f23f66e42340ca8e6aa8cdaef492ed25ff70 100644 (file)
 
 #include "launch.h"
 
+#if __GNUC__ >= 4
+OSStatus SessionCreate(SessionCreationFlags flags, SessionAttributeBits attributes) __attribute__((weak));
+#endif
+
 static int kq = 0;
 
 static void find_fds(launch_data_t o, const char *key __attribute__((unused)), void *context __attribute__((unused)))
index cc23170c5d1c3e535391bb7517da4c55307ba265..87de3cca8bc1e889881f865aa55041b26494bfbd 100644 (file)
@@ -20,6 +20,7 @@
  * 
  * @APPLE_LICENSE_HEADER_END@
  */
+#include <libkern/OSByteOrder.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/fcntl.h>
 #include "launch.h"
 #include "launch_priv.h"
 
+/* __OSBogusByteSwap__() must not really exist in the symbol namespace
+ * in order for the following to generate an error at build time.
+ */
+extern void __OSBogusByteSwap__(void);
+
+#define host2big(x)                            \
+       ({ typeof (x) _X, _x = (x);             \
+        switch (sizeof(_x)) {                  \
+        case 8:                                \
+               _X = OSSwapHostToBigInt64(_x);  \
+               break;                          \
+        case 4:                                \
+               _X = OSSwapHostToBigInt32(_x);  \
+               break;                          \
+        case 2:                                \
+               _X = OSSwapHostToBigInt16(_x);  \
+               break;                          \
+        case 1:                                \
+               _X = _x;                        \
+               break;                          \
+        default:                               \
+               __OSBogusByteSwap__();          \
+               break;                          \
+        }                                      \
+        _X;                                    \
+        })
+
+
+#define big2host(x)                            \
+       ({ typeof (x) _X, _x = (x);             \
+        switch (sizeof(_x)) {                  \
+        case 8:                                \
+               _X = OSSwapBigToHostInt64(_x);  \
+               break;                          \
+        case 4:                                \
+               _X = OSSwapBigToHostInt32(_x);  \
+               break;                          \
+        case 2:                                \
+               _X = OSSwapBigToHostInt16(_x);  \
+               break;                          \
+        case 1:                                \
+               _X = _x;                        \
+               break;                          \
+        default:                               \
+               __OSBogusByteSwap__();          \
+               break;                          \
+        }                                      \
+        _X;                                    \
+        })
+
+
+struct launch_msg_header {
+       uint64_t magic;
+       uint64_t len;
+};
+
+#define LAUNCH_MSG_HEADER_MAGIC 0xD2FEA02366B39A41ull
+
 struct _launch_data {
-       launch_data_type_t type;
+       int type;
        union {
                struct {
                        launch_data_t *_array;
@@ -464,14 +523,32 @@ void launchd_close(launch_t lh)
 
 static void make_msg_and_cmsg(launch_data_t d, void **where, size_t *len, int **fd_where, size_t *fdcnt)
 {
+       launch_data_t o_in_w;
        size_t i;
 
        *where = realloc(*where, *len + sizeof(struct _launch_data));
-       memcpy(*where + *len, d, sizeof(struct _launch_data));
+
+       o_in_w = *where + *len;
+       memset(o_in_w, 0, sizeof(struct _launch_data));
        *len += sizeof(struct _launch_data);
 
+       o_in_w->type = host2big(d->type);
+
        switch (d->type) {
+       case LAUNCH_DATA_INTEGER:
+               o_in_w->number = host2big(d->number);
+               break;
+       case LAUNCH_DATA_REAL:
+               o_in_w->float_num = host2big(d->float_num);
+               break;
+       case LAUNCH_DATA_BOOL:
+               o_in_w->boolean = host2big(d->boolean);
+               break;
+       case LAUNCH_DATA_ERRNO:
+               o_in_w->err = host2big(d->err);
+               break;
        case LAUNCH_DATA_FD:
+               o_in_w->fd = host2big(d->fd);
                if (d->fd != -1) {
                        *fd_where = realloc(*fd_where, (*fdcnt + 1) * sizeof(int));
                        (*fd_where)[*fdcnt] = d->fd;
@@ -479,17 +556,20 @@ static void make_msg_and_cmsg(launch_data_t d, void **where, size_t *len, int **
                }
                break;
        case LAUNCH_DATA_STRING:
+               o_in_w->string_len = host2big(d->string_len);
                *where = realloc(*where, *len + strlen(d->string) + 1);
                memcpy(*where + *len, d->string, strlen(d->string) + 1);
                *len += strlen(d->string) + 1;
                break;
        case LAUNCH_DATA_OPAQUE:
+               o_in_w->opaque_size = host2big(d->opaque_size);
                *where = realloc(*where, *len + d->opaque_size);
                memcpy(*where + *len, d->opaque, d->opaque_size);
                *len += d->opaque_size;
                break;
        case LAUNCH_DATA_DICTIONARY:
        case LAUNCH_DATA_ARRAY:
+               o_in_w->_array_cnt = host2big(d->_array_cnt);
                *where = realloc(*where, *len + (d->_array_cnt * sizeof(launch_data_t)));
                memcpy(*where + *len, d->_array, d->_array_cnt * sizeof(launch_data_t));
                *len += d->_array_cnt * sizeof(launch_data_t);
@@ -505,42 +585,48 @@ static void make_msg_and_cmsg(launch_data_t d, void **where, size_t *len, int **
 static launch_data_t make_data(launch_t conn, size_t *data_offset, size_t *fdoffset)
 {
        launch_data_t r = conn->recvbuf + *data_offset;
-       size_t i;
+       size_t i, tmpcnt;
 
        if ((conn->recvlen - *data_offset) < sizeof(struct _launch_data))
                return NULL;
        *data_offset += sizeof(struct _launch_data);
 
-       switch (r->type) {
+       switch (big2host(r->type)) {
        case LAUNCH_DATA_DICTIONARY:
        case LAUNCH_DATA_ARRAY:
-               if ((conn->recvlen - *data_offset) < (r->_array_cnt * sizeof(launch_data_t))) {
+               tmpcnt = big2host(r->_array_cnt);
+               if ((conn->recvlen - *data_offset) < (tmpcnt * sizeof(launch_data_t))) {
                        errno = EAGAIN;
                        return NULL;
                }
                r->_array = conn->recvbuf + *data_offset;
-               *data_offset += r->_array_cnt * sizeof(launch_data_t);
-               for (i = 0; i < r->_array_cnt; i++) {
+               *data_offset += tmpcnt * sizeof(launch_data_t);
+               for (i = 0; i < tmpcnt; i++) {
                        r->_array[i] = make_data(conn, data_offset, fdoffset);
                        if (r->_array[i] == NULL)
                                return NULL;
                }
+               r->_array_cnt = tmpcnt;
                break;
        case LAUNCH_DATA_STRING:
-               if ((conn->recvlen - *data_offset) < (r->string_len + 1)) {
+               tmpcnt = big2host(r->string_len);
+               if ((conn->recvlen - *data_offset) < (tmpcnt + 1)) {
                        errno = EAGAIN;
                        return NULL;
                }
                r->string = conn->recvbuf + *data_offset;
-               *data_offset += r->string_len + 1;
+               r->string_len = tmpcnt;
+               *data_offset += tmpcnt + 1;
                break;
        case LAUNCH_DATA_OPAQUE:
-               if ((conn->recvlen - *data_offset) < r->opaque_size) {
+               tmpcnt = big2host(r->opaque_size);
+               if ((conn->recvlen - *data_offset) < tmpcnt) {
                        errno = EAGAIN;
                        return NULL;
                }
                r->opaque = conn->recvbuf + *data_offset;
-               *data_offset += r->opaque_size;
+               r->opaque_size = tmpcnt;
+               *data_offset += tmpcnt;
                break;
        case LAUNCH_DATA_FD:
                if (r->fd != -1) {
@@ -549,9 +635,16 @@ static launch_data_t make_data(launch_t conn, size_t *data_offset, size_t *fdoff
                }
                break;
        case LAUNCH_DATA_INTEGER:
+               r->number = big2host(r->number);
+               break;
        case LAUNCH_DATA_REAL:
+               r->float_num = big2host(r->float_num);
+               break;
        case LAUNCH_DATA_BOOL:
+               r->boolean = big2host(r->boolean);
+               break;
        case LAUNCH_DATA_ERRNO:
+               r->err = big2host(r->err);
                break;
        default:
                errno = EINVAL;
@@ -559,25 +652,44 @@ static launch_data_t make_data(launch_t conn, size_t *data_offset, size_t *fdoff
                break;
        }
 
+       r->type = big2host(r->type);
+
        return r;
 }
 
 int launchd_msg_send(launch_t lh, launch_data_t d)
 {
+       struct launch_msg_header lmh;
        struct cmsghdr *cm = NULL;
        struct msghdr mh;
-       struct iovec iov;
-       int r;
+       struct iovec iov[2];
        size_t sentctrllen = 0;
+       int r;
 
        memset(&mh, 0, sizeof(mh));
 
-       mh.msg_iov = &iov;
-        mh.msg_iovlen = 1;
+       if (d) {
+               uint64_t msglen = lh->sendlen;
 
-       if (d)
                make_msg_and_cmsg(d, &lh->sendbuf, &lh->sendlen, &lh->sendfds, &lh->sendfdcnt);
 
+               msglen = (lh->sendlen - msglen) + sizeof(struct launch_msg_header);
+               lmh.len = host2big(msglen);
+               lmh.magic = host2big(LAUNCH_MSG_HEADER_MAGIC);
+
+               iov[0].iov_base = &lmh;
+               iov[0].iov_len = sizeof(lmh);
+               mh.msg_iov = iov;
+               mh.msg_iovlen = 2;
+       } else {
+               mh.msg_iov = iov + 1;
+               mh.msg_iovlen = 1;
+       }
+
+       iov[1].iov_base = lh->sendbuf;
+       iov[1].iov_len = lh->sendlen;
+
+
        if (lh->sendfdcnt > 0) {
                sentctrllen = mh.msg_controllen = CMSG_SPACE(lh->sendfdcnt * sizeof(int));
                cm = alloca(mh.msg_controllen);
@@ -592,9 +704,6 @@ int launchd_msg_send(launch_t lh, launch_data_t d)
                memcpy(CMSG_DATA(cm), lh->sendfds, lh->sendfdcnt * sizeof(int));
        }
 
-       iov.iov_base = lh->sendbuf;
-       iov.iov_len = lh->sendlen;
-
        if ((r = sendmsg(lh->fd, &mh, 0)) == -1) {
                return -1;
        } else if (r == 0) {
@@ -605,6 +714,10 @@ int launchd_msg_send(launch_t lh, launch_data_t d)
                return -1;
        }
 
+       if (d) {
+               r -= sizeof(struct launch_msg_header);
+       }
+
        lh->sendlen -= r;
        if (lh->sendlen > 0) {
                memmove(lh->sendbuf, lh->sendbuf + r, lh->sendlen);
@@ -700,7 +813,7 @@ out:
 int launchd_msg_recv(launch_t lh, void (*cb)(launch_data_t, void *), void *context)
 {
        struct cmsghdr *cm = alloca(4096); 
-       launch_data_t rmsg;
+       launch_data_t rmsg = NULL;
        size_t data_offset, fd_offset;
         struct msghdr mh;
         struct iovec iov;
@@ -734,13 +847,33 @@ int launchd_msg_recv(launch_t lh, void (*cb)(launch_data_t, void *), void *conte
                lh->recvfdcnt += (mh.msg_controllen - sizeof(struct cmsghdr)) / sizeof(int);
        }
 
-parse_more:
-       data_offset = 0;
-       fd_offset = 0;
+       r = 0;
+
+       while (lh->recvlen > 0) {
+               struct launch_msg_header *lmhp = lh->recvbuf;
+               uint64_t tmplen;
+               data_offset = sizeof(struct launch_msg_header);
+               fd_offset = 0;
+
+               if (lh->recvlen < sizeof(struct launch_msg_header))
+                       goto need_more_data;
+
+               tmplen = big2host(lmhp->len);
+
+               if (big2host(lmhp->magic) != LAUNCH_MSG_HEADER_MAGIC || tmplen <= sizeof(struct launch_msg_header)) {
+                       errno = EBADRPC;
+                       goto out_bad;
+               }
+
+               if (lh->recvlen < tmplen) {
+                       goto need_more_data;
+               }
 
-       rmsg = make_data(lh, &data_offset, &fd_offset);
+               if ((rmsg = make_data(lh, &data_offset, &fd_offset)) == NULL) {
+                       errno = EBADRPC;
+                       goto out_bad;
+               }
 
-       if (rmsg) {
                cb(rmsg, context);
 
                lh->recvlen -= data_offset;
@@ -758,17 +891,14 @@ parse_more:
                        free(lh->recvfds);
                        lh->recvfds = malloc(0);
                }
-
-               if (lh->recvlen > 0)
-                       goto parse_more;
-               else
-                       r = 0;
-       } else {
-               errno = EAGAIN;
-               r = -1;
        }
 
        return r;
+
+need_more_data:
+       errno = EAGAIN;
+out_bad:
+       return -1;
 }
 
 launch_data_t launch_data_copy(launch_data_t o)
index 8e3eed79f8471533f50077e9ebedd95c0ea33bac..01d3ef99829da2213cca32694a70cea265872990 100644 (file)
@@ -278,14 +278,15 @@ delete_bootstrap_services(bootstrap_info_t *bootstrap)
                if (bootstrap != servicep->bootstrap)
                        continue;
 
-               if (!servicep->isActive || !servicep->server) {
-                       delete_service(servicep);
-                       continue;
-               }
-
                serverp = servicep->server;
+
+               if (servicep->isActive && serverp)
+                       serverp->active_services--;
+
                delete_service(servicep);
-               serverp->active_services--;
+
+               if (!serverp)
+                       continue;
                if (!active_server(serverp))
                        delete_server(serverp);
        }
index 9a89261b3665f36f4c3ac12e952559d2b95deafc..551448af11f659a1747134a69cec288e0a8fb801 100644 (file)
@@ -252,11 +252,10 @@ if [ -f /Library/Preferences/com.apple.sharing.firewall.plist ]; then
 fi
 
 # Load [ideally on demand] daemons
-/usr/libexec/register_mach_bootstrap_servers /etc/mach_init.d
 if [ "${SafeBoot}" = "-x" ]; then
-       launchctl load /System/Library/LaunchDaemons
+       launchctl load /System/Library/LaunchDaemons /etc/mach_init.d
 else
-       launchctl load /Library/LaunchDaemons /System/Library/LaunchDaemons
+       launchctl load /Library/LaunchDaemons /System/Library/LaunchDaemons /etc/mach_init.d
        SystemStarter ${VerboseFlag}
 fi
 
index 247691164b670f56c4721eaf4a7dd294d84bbcb7..eb0d7cca455192ead6495b64bce4294ca0ea95c5 100644 (file)
@@ -149,7 +149,7 @@ static CFPropertyListRef CreateMyPropertyListFromFile(const char *posixfile)
        SInt32            errorCode;
        CFURLRef          fileURL;
 
-       fileURL = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, posixfile, strlen(posixfile), false);
+       fileURL = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (const UInt8 *)posixfile, strlen(posixfile), false);
        if (!fileURL)
                fprintf(stderr, "%s: CFURLCreateFromFileSystemRepresentation(%s) failed\n", getprogname(), posixfile);
        if (!CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault, fileURL, &resourceData, NULL, NULL, &errorCode))
index 7bc333fb8908503d68064bf000a71942c30af1da..ee1c1ae137dbb2ebf3dd1a4a28b190dd23bc7d4e 100644 (file)
@@ -42,6 +42,9 @@ int main(int argc, char *argv[])
                exit(EXIT_FAILURE);
        }
 
+       if (stat(argv[1], &sb) == 0)
+               exit(EXIT_SUCCESS);
+
        EV_SET(&kev, 0, EVFILT_FS, EV_ADD, 0, 0, 0);
 
        if (kevent(kq, &kev, 1, NULL, 0, NULL) == -1) {