]> asedeno.scripts.mit.edu Git - PuTTY.git/blobdiff - unix/uxpty.c
Rework handling of asynchronous connect(2) errors on Unix.
[PuTTY.git] / unix / uxpty.c
index 33cc2c1e702d4e87574f917a75500bfe19d117ae..39f96f126afd9a347f3c46caf2bd7c8fed914015 100644 (file)
@@ -180,6 +180,8 @@ static struct utmpx utmp_entry;
  */
 char **pty_argv;
 
+char *pty_osx_envrestore_prefix;
+
 static void pty_close(Pty pty);
 static void pty_try_write(Pty pty);
 
@@ -763,18 +765,6 @@ static const char *pty_init(void *frontend, void **backend_handle, Conf *conf,
     if (pty->master_fd < 0)
        pty_open_master(pty);
 
-    /*
-     * Set the backspace character to be whichever of ^H and ^? is
-     * specified by bksp_is_delete.
-     */
-    {
-       struct termios attrs;
-       tcgetattr(pty->master_fd, &attrs);
-       attrs.c_cc[VERASE] = conf_get_int(conf, CONF_bksp_is_delete)
-           ? '\177' : '\010';
-       tcsetattr(pty->master_fd, TCSANOW, &attrs);
-    }
-
 #ifndef OMIT_UTMP
     /*
      * Stamp utmp (that is, tell the utmp helper process to do so),
@@ -815,10 +805,40 @@ static const char *pty_init(void *frontend, void **backend_handle, Conf *conf,
     }
 
     if (pid == 0) {
+        struct termios attrs;
+
        /*
         * We are the child.
         */
 
+        if (pty_osx_envrestore_prefix) {
+            int plen = strlen(pty_osx_envrestore_prefix);
+            extern char **environ;
+            char **ep;
+
+          restart_osx_env_restore:
+            for (ep = environ; *ep; ep++) {
+                char *e = *ep;
+
+                if (!strncmp(e, pty_osx_envrestore_prefix, plen)) {
+                    int unset = (e[plen] == 'u');
+                    char *pname = dupprintf("%.*s", (int)strcspn(e, "="), e);
+                    char *name = pname + plen + 1;
+                    char *value = e + strcspn(e, "=");
+                    if (*value) value++;
+                    value = dupstr(value);
+                    if (unset)
+                        unsetenv(name);
+                    else
+                        setenv(name, value, 1);
+                    unsetenv(pname);
+                    sfree(pname);
+                    sfree(value);
+                    goto restart_osx_env_restore;
+                }
+            }
+        }
+
        slavefd = pty_open_slave(pty);
        if (slavefd < 0) {
            perror("slave pty: open");
@@ -837,6 +857,34 @@ static const char *pty_init(void *frontend, void **backend_handle, Conf *conf,
 #endif
        pgrp = getpid();
        tcsetpgrp(0, pgrp);
+
+        /*
+         * Set up configuration-dependent termios settings on the new
+         * pty. Linux would have let us do this on the pty master
+         * before we forked, but that fails on OS X, so we do it here
+         * instead.
+         */
+       if (tcgetattr(0, &attrs) == 0) {
+            /*
+             * Set the backspace character to be whichever of ^H and
+             * ^? is specified by bksp_is_delete.
+             */
+            attrs.c_cc[VERASE] = conf_get_int(conf, CONF_bksp_is_delete)
+                ? '\177' : '\010';
+
+            /*
+             * Set the IUTF8 bit iff the character set is UTF-8.
+             */
+#ifdef IUTF8
+            if (frontend_is_utf8(frontend))
+                attrs.c_iflag |= IUTF8;
+            else
+                attrs.c_iflag &= ~IUTF8;
+#endif
+
+            tcsetattr(0, TCSANOW, &attrs);
+        }
+
        setpgid(pgrp, pgrp);
         {
             int ptyfd = open(pty->name, O_WRONLY, 0);
@@ -894,14 +942,14 @@ static const char *pty_init(void *frontend, void **backend_handle, Conf *conf,
        /*
         * SIGINT, SIGQUIT and SIGPIPE may have been set to ignored by
         * our parent, particularly by things like sh -c 'pterm &' and
-        * some window or session managers. SIGCHLD, meanwhile, was
-        * blocked during pt_main() startup. Reverse all this for our
-        * child process.
+        * some window or session managers. SIGPIPE was also
+        * (potentially) blocked by us during startup. Reverse all
+        * this for our child process.
         */
        putty_signal(SIGINT, SIG_DFL);
        putty_signal(SIGQUIT, SIG_DFL);
        putty_signal(SIGPIPE, SIG_DFL);
-       block_signal(SIGCHLD, 0);
+       block_signal(SIGPIPE, 0);
        if (pty_argv) {
             /*
              * Exec the exact argument list we were given.
@@ -1200,6 +1248,7 @@ Backend pty_backend = {
     pty_provide_logctx,
     pty_unthrottle,
     pty_cfg_info,
+    NULL /* test_for_upstream */,
     "pty",
     -1,
     0