+ pid = fork();
+ if (pid) {
+ if ((-1 != pid) && (-1 != channel[1])) {
+ int child_errno = 0;
+ int bytes = sizeof(int);
+ int n;
+ char *p = (char*)&child_errno;
+ close(channel[1]);
+ /* Try to read child errno from channel. */
+ while ((bytes > 0) &&
+ (n = read(channel[0], p, bytes))) {
+ if (-1 == n) {
+ if (EINTR == errno) {
+ continue;
+ } else {
+ break;
+ }
+ } else {
+ bytes -= n;
+ p += n;
+ }
+ }
+ if (child_errno) {
+ waitpid(pid, NULL, 0);
+ /* Our convention to tell Lisp that it was the exec that
+ * failed, not the fork. */
+ pid = -2;
+ errno = child_errno;
+ }
+ }
+ return pid;
+ }
+ close (channel[0]);
+
+ /* Put us in our own process group, but only if we need not
+ * share stdin with our parent. In the latter case we claim
+ * control of the terminal. */
+ if (sin >= 0) {
+#if defined(LISP_FEATURE_HPUX) || defined(LISP_FEATURE_OPENBSD)
+ setsid();