<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" /><style type="text/css"><!--
#msg dl { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre, #msg p { overflow: auto; background: #ffc; border: 1px #fc0 solid; padding: 6px; }
#msg ul { overflow: auto; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<title>[23478] trunk/launchd/src</title>
</head>
<body>

<div id="msg">
<dl>
<dt>Revision</dt> <dd><a href="http://trac.macosforge.org/projects/launchd/changeset/23478">23478</a></dd>
<dt>Author</dt> <dd>zarzycki@apple.com</dd>
<dt>Date</dt> <dd>2008-01-09 09:35:12 -0800 (Wed, 09 Jan 2008)</dd>
</dl>

<h3>Log Message</h3>
<pre>More misc. branch hints, plus basic (and untested) &quot;StandardInPath&quot; support.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunklaunchdsrclaunchdplist5">trunk/launchd/src/launchd.plist.5</a></li>
<li><a href="#trunklaunchdsrclaunchd_core_logicc">trunk/launchd/src/launchd_core_logic.c</a></li>
<li><a href="#trunklaunchdsrcliblaunch_publich">trunk/launchd/src/liblaunch_public.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunklaunchdsrclaunchdplist5"></a>
<div class="modfile"><h4>Modified: trunk/launchd/src/launchd.plist.5 (23477 => 23478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/launchd/src/launchd.plist.5        2008-01-09 17:30:02 UTC (rev 23477)
+++ trunk/launchd/src/launchd.plist.5        2008-01-09 17:35:12 UTC (rev 23478)
</span><span class="lines">@@ -226,6 +226,9 @@
</span><span class="cx"> .It Sy Month &lt;integer&gt;
</span><span class="cx"> The month on which this job will be run.
</span><span class="cx"> .El
</span><ins>+.It Sy StandardInPath &lt;string&gt;
+This optional key specifies what file should be used for data being supplied to stdin when using
+.Xr stdio 3 .
</ins><span class="cx"> .It Sy StandardOutPath &lt;string&gt;
</span><span class="cx"> This optional key specifies what file should be used for data being sent to stdout when using
</span><span class="cx"> .Xr stdio 3 .
</span></span></pre></div>
<a id="trunklaunchdsrclaunchd_core_logicc"></a>
<div class="modfile"><h4>Modified: trunk/launchd/src/launchd_core_logic.c (23477 => 23478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/launchd/src/launchd_core_logic.c        2008-01-09 17:30:02 UTC (rev 23477)
+++ trunk/launchd/src/launchd_core_logic.c        2008-01-09 17:35:12 UTC (rev 23478)
</span><span class="lines">@@ -331,6 +331,7 @@
</span><span class="cx">         char *workingdir;
</span><span class="cx">         char *username;
</span><span class="cx">         char *groupname;
</span><ins>+        char *stdinpath;
</ins><span class="cx">         char *stdoutpath;
</span><span class="cx">         char *stderrpath;
</span><span class="cx">         char *alt_exc_handler;
</span><span class="lines">@@ -343,7 +344,8 @@
</span><span class="cx">         pid_t p;
</span><span class="cx">         int argc;
</span><span class="cx">         int last_exit_status;
</span><del>-        int forkfd;
</del><ins>+        int stdin_fd;
+        int fork_fd;
</ins><span class="cx">         int log_redirect_fd;
</span><span class="cx">         int nice;
</span><span class="cx">         unsigned int timeout;
</span><span class="lines">@@ -458,7 +460,7 @@
</span><span class="cx"> static size_t total_anon_children;
</span><span class="cx"> static mach_port_t the_exception_server;
</span><span class="cx"> static bool did_first_per_user_launchd_BootCache_hack;
</span><del>-#define JOB_BOOTCACHE_HACK_CHECK(j)        (j-&gt;per_user &amp;&amp; !did_first_per_user_launchd_BootCache_hack &amp;&amp; (j-&gt;mach_uid &gt;= 500) &amp;&amp; (j-&gt;mach_uid != (uid_t)-2))
</del><ins>+#define JOB_BOOTCACHE_HACK_CHECK(j)        (unlikely(j-&gt;per_user &amp;&amp; !did_first_per_user_launchd_BootCache_hack &amp;&amp; (j-&gt;mach_uid &gt;= 500) &amp;&amp; (j-&gt;mach_uid != (uid_t)-2)))
</ins><span class="cx"> static jobmgr_t background_jobmgr;
</span><span class="cx"> static job_t workaround_5477111;
</span><span class="cx"> 
</span><span class="lines">@@ -576,6 +578,9 @@
</span><span class="cx">         if (j-&gt;prog &amp;&amp; (tmp = launch_data_new_string(j-&gt;prog))) {
</span><span class="cx">                 launch_data_dict_insert(r, tmp, LAUNCH_JOBKEY_PROGRAM);
</span><span class="cx">         }
</span><ins>+        if (j-&gt;stdinpath &amp;&amp; (tmp = launch_data_new_string(j-&gt;stdinpath))) {
+                launch_data_dict_insert(r, tmp, LAUNCH_JOBKEY_STANDARDINPATH);
+        }
</ins><span class="cx">         if (j-&gt;stdoutpath &amp;&amp; (tmp = launch_data_new_string(j-&gt;stdoutpath))) {
</span><span class="cx">                 launch_data_dict_insert(r, tmp, LAUNCH_JOBKEY_STANDARDOUTPATH);
</span><span class="cx">         }
</span><span class="lines">@@ -810,10 +815,14 @@
</span><span class="cx">                 job_set_global_on_demand(j, false);
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        if (!job_assumes(j, j-&gt;forkfd == 0)) {
-                job_assumes(j, runtime_close(j-&gt;forkfd) != -1);
</del><ins>+        if (!job_assumes(j, j-&gt;fork_fd == 0)) {
+                job_assumes(j, runtime_close(j-&gt;fork_fd) != -1);
</ins><span class="cx">         }
</span><span class="cx"> 
</span><ins>+        if (j-&gt;stdin_fd) {
+                job_assumes(j, runtime_close(j-&gt;stdin_fd) != -1);
+        }
+
</ins><span class="cx">         if (!job_assumes(j, j-&gt;log_redirect_fd == 0)) {
</span><span class="cx">                 job_assumes(j, runtime_close(j-&gt;log_redirect_fd) != -1);
</span><span class="cx">         }
</span><span class="lines">@@ -872,6 +881,9 @@
</span><span class="cx">         if (j-&gt;groupname) {
</span><span class="cx">                 free(j-&gt;groupname);
</span><span class="cx">         }
</span><ins>+        if (j-&gt;stdinpath) {
+                free(j-&gt;stdinpath);
+        }
</ins><span class="cx">         if (j-&gt;stdoutpath) {
</span><span class="cx">                 free(j-&gt;stdoutpath);
</span><span class="cx">         }
</span><span class="lines">@@ -1499,6 +1511,17 @@
</span><span class="cx">                         where2put = &amp;j-&gt;stdoutpath;
</span><span class="cx">                 } else if (strcasecmp(key, LAUNCH_JOBKEY_STANDARDERRORPATH) == 0) {
</span><span class="cx">                         where2put = &amp;j-&gt;stderrpath;
</span><ins>+                } else if (strcasecmp(key, LAUNCH_JOBKEY_STANDARDINPATH) == 0) {
+                        where2put = &amp;j-&gt;stdinpath;
+                        j-&gt;stdin_fd = _fd(open(value, O_RDONLY|O_CREAT|O_NOCTTY|O_NONBLOCK, DEFFILEMODE));
+                        if (job_assumes(j, j-&gt;stdin_fd != -1)) {
+                                /* open() should not block, but regular IO by the job should */
+                                job_assumes(j, fcntl(j-&gt;stdin_fd, F_SETFL, 0) != -1);
+                                /* XXX -- EV_CLEAR should make named pipes happy? */
+                                job_assumes(j, kevent_mod(j-&gt;stdin_fd, EVFILT_READ, EV_ADD|EV_CLEAR, 0, 0, j) != -1);
+                        } else {
+                                j-&gt;stdin_fd = 0;
+                        }
</ins><span class="cx">                 } else if (strcasecmp(key, LAUNCH_JOBKEY_SANDBOXPROFILE) == 0) {
</span><span class="cx">                         where2put = &amp;j-&gt;seatbelt_profile;
</span><span class="cx">                 }
</span><span class="lines">@@ -2094,9 +2117,9 @@
</span><span class="cx">                 }
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        if (j-&gt;forkfd) {
-                job_assumes(j, runtime_close(j-&gt;forkfd) != -1);
-                j-&gt;forkfd = 0;
</del><ins>+        if (j-&gt;fork_fd) {
+                job_assumes(j, runtime_close(j-&gt;fork_fd) != -1);
+                j-&gt;fork_fd = 0;
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         if (j-&gt;anonymous) {
</span><span class="lines">@@ -2460,6 +2483,8 @@
</span><span class="cx"> {
</span><span class="cx">         if (ident == j-&gt;log_redirect_fd) {
</span><span class="cx">                 job_log_stdouterr(j);
</span><ins>+        } else if (ident == j-&gt;stdin_fd) {
+                job_dispatch(j, true);
</ins><span class="cx">         } else {
</span><span class="cx">                 socketgroup_callback(j);
</span><span class="cx">         }
</span><span class="lines">@@ -2580,7 +2605,7 @@
</span><span class="cx">                 return;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        if (job_active(j)) {
</del><ins>+        if (unlikely(job_active(j))) {
</ins><span class="cx">                 job_log(j, LOG_DEBUG, &quot;Already started&quot;);
</span><span class="cx">                 return;
</span><span class="cx">         }
</span><span class="lines">@@ -2611,7 +2636,7 @@
</span><span class="cx"> 
</span><span class="cx">         j-&gt;sent_sigterm_time = 0;
</span><span class="cx"> 
</span><del>-        if (!j-&gt;legacy_mach_job) {
</del><ins>+        if (likely(!j-&gt;legacy_mach_job)) {
</ins><span class="cx">                 sipc = (!SLIST_EMPTY(&amp;j-&gt;sockets) || !SLIST_EMPTY(&amp;j-&gt;machservices));
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -2623,7 +2648,7 @@
</span><span class="cx"> 
</span><span class="cx">         job_assumes(j, socketpair(AF_UNIX, SOCK_STREAM, 0, execspair) != -1);
</span><span class="cx"> 
</span><del>-        if (!j-&gt;legacy_mach_job &amp;&amp; job_assumes(j, pipe(oepair) != -1)) {
</del><ins>+        if (likely(!j-&gt;legacy_mach_job) &amp;&amp; job_assumes(j, pipe(oepair) != -1)) {
</ins><span class="cx">                 j-&gt;log_redirect_fd = _fd(oepair[0]);
</span><span class="cx">                 job_assumes(j, fcntl(j-&gt;log_redirect_fd, F_SETFL, O_NONBLOCK) != -1);
</span><span class="cx">                 job_assumes(j, kevent_mod(j-&gt;log_redirect_fd, EVFILT_READ, EV_ADD, 0, 0, j) != -1);
</span><span class="lines">@@ -2640,14 +2665,14 @@
</span><span class="cx">                         job_assumes(j, runtime_close(spair[0]) == 0);
</span><span class="cx">                         job_assumes(j, runtime_close(spair[1]) == 0);
</span><span class="cx">                 }
</span><del>-                if (!j-&gt;legacy_mach_job) {
</del><ins>+                if (likely(!j-&gt;legacy_mach_job)) {
</ins><span class="cx">                         job_assumes(j, runtime_close(oepair[0]) != -1);
</span><span class="cx">                         job_assumes(j, runtime_close(oepair[1]) != -1);
</span><span class="cx">                         j-&gt;log_redirect_fd = 0;
</span><span class="cx">                 }
</span><span class="cx">                 break;
</span><span class="cx">         case 0:
</span><del>-                if (_vproc_post_fork_ping()) {
</del><ins>+                if (unlikely(_vproc_post_fork_ping())) {
</ins><span class="cx">                         _exit(EXIT_FAILURE);
</span><span class="cx">                 }
</span><span class="cx">                 if (!j-&gt;legacy_mach_job) {
</span><span class="lines">@@ -2679,16 +2704,16 @@
</span><span class="cx">                         did_first_per_user_launchd_BootCache_hack = true;
</span><span class="cx">                 }
</span><span class="cx"> 
</span><del>-                if (!j-&gt;legacy_mach_job) {
</del><ins>+                if (likely(!j-&gt;legacy_mach_job)) {
</ins><span class="cx">                         job_assumes(j, runtime_close(oepair[1]) != -1);
</span><span class="cx">                 }
</span><span class="cx">                 j-&gt;p = c;
</span><del>-                if (j-&gt;hopefully_exits_first) {
</del><ins>+                if (unlikely(j-&gt;hopefully_exits_first)) {
</ins><span class="cx">                         j-&gt;mgr-&gt;hopefully_first_cnt++;
</span><del>-                } else if (!j-&gt;hopefully_exits_last) {
</del><ins>+                } else if (likely(!j-&gt;hopefully_exits_last)) {
</ins><span class="cx">                         j-&gt;mgr-&gt;normal_active_cnt++;
</span><span class="cx">                 }
</span><del>-                j-&gt;forkfd = _fd(execspair[0]);
</del><ins>+                j-&gt;fork_fd = _fd(execspair[0]);
</ins><span class="cx">                 job_assumes(j, runtime_close(execspair[1]) == 0);
</span><span class="cx">                 if (sipc) {
</span><span class="cx">                         job_assumes(j, runtime_close(spair[1]) == 0);
</span><span class="lines">@@ -2700,7 +2725,7 @@
</span><span class="cx">                         job_reap(j);
</span><span class="cx">                 }
</span><span class="cx"> 
</span><del>-                if (!j-&gt;stall_before_exec) {
</del><ins>+                if (likely(!j-&gt;stall_before_exec)) {
</ins><span class="cx">                         job_uncork_fork(j);
</span><span class="cx">                 }
</span><span class="cx">                 break;
</span><span class="lines">@@ -2745,7 +2770,7 @@
</span><span class="cx"> 
</span><span class="cx">         job_setup_attributes(j);
</span><span class="cx"> 
</span><del>-        if (j-&gt;argv &amp;&amp; j-&gt;globargv) {
</del><ins>+        if (unlikely(j-&gt;argv &amp;&amp; j-&gt;globargv)) {
</ins><span class="cx">                 g.gl_offs = 1;
</span><span class="cx">                 for (i = 0; i &lt; j-&gt;argc; i++) {
</span><span class="cx">                         if (i &gt; 0) {
</span><span class="lines">@@ -2772,18 +2797,18 @@
</span><span class="cx">                 argv[2] = NULL;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        if (!j-&gt;inetcompat) {
</del><ins>+        if (likely(!j-&gt;inetcompat)) {
</ins><span class="cx">                 argv++;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        if (j-&gt;wait4debugger) {
</del><ins>+        if (unlikely(j-&gt;wait4debugger)) {
</ins><span class="cx">                 job_log(j, LOG_WARNING, &quot;Spawned and waiting for the debugger to attach before continuing...&quot;);
</span><span class="cx">                 spflags |= POSIX_SPAWN_START_SUSPENDED;
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         job_assumes(j, posix_spawnattr_setflags(&amp;spattr, spflags) == 0);
</span><span class="cx"> 
</span><del>-        if (j-&gt;j_binpref_cnt) {
</del><ins>+        if (unlikely(j-&gt;j_binpref_cnt)) {
</ins><span class="cx">                 job_assumes(j, posix_spawnattr_setbinpref_np(&amp;spattr, j-&gt;j_binpref_cnt, j-&gt;j_binpref, &amp;binpref_out_cnt) == 0);
</span><span class="cx">                 job_assumes(j, binpref_out_cnt == j-&gt;j_binpref_cnt);
</span><span class="cx">         }
</span><span class="lines">@@ -2811,7 +2836,7 @@
</span><span class="cx"> 
</span><span class="cx">         psf = j-&gt;prog ? posix_spawn : posix_spawnp;
</span><span class="cx"> 
</span><del>-        if (!j-&gt;inetcompat) {
</del><ins>+        if (likely(!j-&gt;inetcompat)) {
</ins><span class="cx">                 file2exec = j-&gt;prog ? j-&gt;prog : argv[0];
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -2964,22 +2989,22 @@
</span><span class="cx">         strlcpy(loginname, pwe-&gt;pw_name, sizeof(loginname));
</span><span class="cx">         strlcpy(homedir, pwe-&gt;pw_dir, sizeof(homedir));
</span><span class="cx"> 
</span><del>-        if (pwe-&gt;pw_expire &amp;&amp; time(NULL) &gt;= pwe-&gt;pw_expire) {
</del><ins>+        if (unlikely(pwe-&gt;pw_expire &amp;&amp; time(NULL) &gt;= pwe-&gt;pw_expire)) {
</ins><span class="cx">                 job_log(j, LOG_ERR, &quot;Expired account&quot;);
</span><span class="cx">                 _exit(EXIT_FAILURE);
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx"> 
</span><del>-        if (j-&gt;username &amp;&amp; strcmp(j-&gt;username, loginname) != 0) {
</del><ins>+        if (unlikely(j-&gt;username &amp;&amp; strcmp(j-&gt;username, loginname) != 0)) {
</ins><span class="cx">                 job_log(j, LOG_WARNING, &quot;Suspicious setup: User \&quot;%s\&quot; maps to user: %s&quot;, j-&gt;username, loginname);
</span><del>-        } else if (j-&gt;mach_uid &amp;&amp; (j-&gt;mach_uid != desired_uid)) {
</del><ins>+        } else if (unlikely(j-&gt;mach_uid &amp;&amp; (j-&gt;mach_uid != desired_uid))) {
</ins><span class="cx">                 job_log(j, LOG_WARNING, &quot;Suspicious setup: UID %u maps to UID %u&quot;, j-&gt;mach_uid, desired_uid);
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         if (j-&gt;groupname) {
</span><span class="cx">                 struct group *gre;
</span><span class="cx"> 
</span><del>-                if ((gre = getgrnam(j-&gt;groupname)) == NULL) {
</del><ins>+                if (unlikely((gre = getgrnam(j-&gt;groupname)) == NULL)) {
</ins><span class="cx">                         job_log(j, LOG_ERR, &quot;getgrnam(\&quot;%s\&quot;) failed&quot;, j-&gt;groupname);
</span><span class="cx">                         _exit(EXIT_FAILURE);
</span><span class="cx">                 }
</span><span class="lines">@@ -3000,7 +3025,7 @@
</span><span class="cx">          * called after setgid(). See 4616864 for more information.
</span><span class="cx">          */
</span><span class="cx"> 
</span><del>-        if (!j-&gt;no_init_groups) {
</del><ins>+        if (likely(!j-&gt;no_init_groups)) {
</ins><span class="cx">                 if (!job_assumes(j, initgroups(loginname, desired_gid) != -1)) {
</span><span class="cx">                         _exit(EXIT_FAILURE);
</span><span class="cx">                 }
</span><span class="lines">@@ -3012,7 +3037,7 @@
</span><span class="cx"> 
</span><span class="cx">         r = confstr(_CS_DARWIN_USER_TEMP_DIR, tmpdirpath, sizeof(tmpdirpath));
</span><span class="cx"> 
</span><del>-        if (r &gt; 0 &amp;&amp; r &lt; sizeof(tmpdirpath)) {
</del><ins>+        if (likely(r &gt; 0 &amp;&amp; r &lt; sizeof(tmpdirpath))) {
</ins><span class="cx">                 setenv(&quot;TMPDIR&quot;, tmpdirpath, 0);
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -3028,7 +3053,7 @@
</span><span class="cx">         struct limititem *li;
</span><span class="cx">         struct envitem *ei;
</span><span class="cx"> 
</span><del>-        if (j-&gt;setnice) {
</del><ins>+        if (unlikely(j-&gt;setnice)) {
</ins><span class="cx">                 job_assumes(j, setpriority(PRIO_PROCESS, 0, j-&gt;nice) != -1);
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -3051,30 +3076,35 @@
</span><span class="cx">                 }
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        if (!j-&gt;inetcompat &amp;&amp; j-&gt;session_create) {
</del><ins>+        if (unlikely(!j-&gt;inetcompat &amp;&amp; j-&gt;session_create)) {
</ins><span class="cx">                 launchd_SessionCreate();
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        if (j-&gt;low_pri_io) {
</del><ins>+        if (unlikely(j-&gt;low_pri_io)) {
</ins><span class="cx">                 job_assumes(j, setiopolicy_np(IOPOL_TYPE_DISK, IOPOL_SCOPE_PROCESS, IOPOL_THROTTLE) != -1);
</span><span class="cx">         }
</span><del>-        if (j-&gt;rootdir) {
</del><ins>+        if (unlikely(j-&gt;rootdir)) {
</ins><span class="cx">                 job_assumes(j, chroot(j-&gt;rootdir) != -1);
</span><span class="cx">                 job_assumes(j, chdir(&quot;.&quot;) != -1);
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         job_postfork_become_user(j);
</span><span class="cx"> 
</span><del>-        if (j-&gt;workingdir) {
</del><ins>+        if (unlikely(j-&gt;workingdir)) {
</ins><span class="cx">                 job_assumes(j, chdir(j-&gt;workingdir) != -1);
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        if (j-&gt;setmask) {
</del><ins>+        if (unlikely(j-&gt;setmask)) {
</ins><span class="cx">                 umask(j-&gt;mask);
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        job_setup_fd(j, STDOUT_FILENO, j-&gt;stdoutpath, O_WRONLY|O_APPEND|O_CREAT);
-        job_setup_fd(j, STDERR_FILENO, j-&gt;stderrpath, O_WRONLY|O_APPEND|O_CREAT);
</del><ins>+        if (j-&gt;stdin_fd) {
+                job_assumes(j, dup2(j-&gt;stdin_fd, STDIN_FILENO) != -1);
+        } else {
+                job_setup_fd(j, STDIN_FILENO,  j-&gt;stdinpath,  O_RDONLY|O_CREAT);
+        }
+        job_setup_fd(j, STDOUT_FILENO, j-&gt;stdoutpath, O_WRONLY|O_CREAT|O_APPEND);
+        job_setup_fd(j, STDERR_FILENO, j-&gt;stderrpath, O_WRONLY|O_CREAT|O_APPEND);
</ins><span class="cx"> 
</span><span class="cx">         jobmgr_setup_env_from_other_jobs(j-&gt;mgr);
</span><span class="cx"> 
</span><span class="lines">@@ -3119,7 +3149,7 @@
</span><span class="cx">         struct dirent *de;
</span><span class="cx">         bool r = 0;
</span><span class="cx"> 
</span><del>-        if (!dd) {
</del><ins>+        if (unlikely(!dd)) {
</ins><span class="cx">                 return -1;
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -3185,7 +3215,7 @@
</span><span class="cx">                 ctime_r(&amp;later, time_string);
</span><span class="cx">                 time_string_len = strlen(time_string);
</span><span class="cx"> 
</span><del>-                if (time_string_len &amp;&amp; time_string[time_string_len - 1] == '\n') {
</del><ins>+                if (likely(time_string_len &amp;&amp; time_string[time_string_len - 1] == '\n')) {
</ins><span class="cx">                         time_string[time_string_len - 1] = '\0';
</span><span class="cx">                 }
</span><span class="cx"> 
</span><span class="lines">@@ -3287,13 +3317,13 @@
</span><span class="cx">                 snprintf(newmsg, newmsgsz, &quot;%s&quot;, msg);
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        if (j-&gt;debug) {
</del><ins>+        if (unlikely(j-&gt;debug)) {
</ins><span class="cx">                 oldmask = setlogmask(LOG_UPTO(LOG_DEBUG));
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         runtime_vsyslog(&amp;attr, newmsg, ap);
</span><span class="cx"> 
</span><del>-        if (j-&gt;debug) {
</del><ins>+        if (unlikely(j-&gt;debug)) {
</ins><span class="cx">                 setlogmask(oldmask);
</span><span class="cx">         }
</span><span class="cx"> }
</span><span class="lines">@@ -4414,9 +4444,9 @@
</span><span class="cx">         job_log(j, LOG_DEBUG, &quot;Uncorking the fork().&quot;);
</span><span class="cx">         /* this unblocks the child and avoids a race
</span><span class="cx">          * between the above fork() and the kevent_mod() */
</span><del>-        job_assumes(j, write(j-&gt;forkfd, &amp;c, sizeof(c)) == sizeof(c));
-        job_assumes(j, runtime_close(j-&gt;forkfd) != -1);
-        j-&gt;forkfd = 0;
</del><ins>+        job_assumes(j, write(j-&gt;fork_fd, &amp;c, sizeof(c)) == sizeof(c));
+        job_assumes(j, runtime_close(j-&gt;fork_fd) != -1);
+        j-&gt;fork_fd = 0;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> jobmgr_t 
</span></span></pre></div>
<a id="trunklaunchdsrcliblaunch_publich"></a>
<div class="modfile"><h4>Modified: trunk/launchd/src/liblaunch_public.h (23477 => 23478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/launchd/src/liblaunch_public.h        2008-01-09 17:30:02 UTC (rev 23477)
+++ trunk/launchd/src/liblaunch_public.h        2008-01-09 17:35:12 UTC (rev 23478)
</span><span class="lines">@@ -85,6 +85,7 @@
</span><span class="cx"> #define LAUNCH_JOBKEY_STARTONMOUNT                &quot;StartOnMount&quot;
</span><span class="cx"> #define LAUNCH_JOBKEY_SOFTRESOURCELIMITS        &quot;SoftResourceLimits&quot;
</span><span class="cx"> #define LAUNCH_JOBKEY_HARDRESOURCELIMITS        &quot;HardResourceLimits&quot;
</span><ins>+#define LAUNCH_JOBKEY_STANDARDINPATH                &quot;StandardInPath&quot;
</ins><span class="cx"> #define LAUNCH_JOBKEY_STANDARDOUTPATH                &quot;StandardOutPath&quot;
</span><span class="cx"> #define LAUNCH_JOBKEY_STANDARDERRORPATH                &quot;StandardErrorPath&quot;
</span><span class="cx"> #define LAUNCH_JOBKEY_DEBUG                        &quot;Debug&quot;
</span></span></pre>
</div>
</div>

</body>
</html>