[BACK]Return to readpass.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

Diff for /src/usr.bin/ssh/readpass.c between version 1.54 and 1.55

version 1.54, 2019/06/28 13:35:04 version 1.55, 2019/11/12 22:34:20
Line 194 
Line 194 
   
         return (allowed);          return (allowed);
 }  }
   
   struct notifier_ctx {
           pid_t pid;
           void (*osigchld)(int);
   };
   
   struct notifier_ctx *
   notify_start(int force_askpass, const char *fmt, ...)
   {
           va_list args;
           char *prompt = NULL;
           int devnull;
           pid_t pid;
           void (*osigchld)(int);
           const char *askpass;
           struct notifier_ctx *ret;
   
           va_start(args, fmt);
           xvasprintf(&prompt, fmt, args);
           va_end(args);
   
           if (fflush(NULL) != 0)
                   error("%s: fflush: %s", __func__, strerror(errno));
           if (!force_askpass && isatty(STDERR_FILENO)) {
                   (void)write(STDERR_FILENO, "\r", 1);
                   (void)write(STDERR_FILENO, prompt, strlen(prompt));
                   (void)write(STDERR_FILENO, "\r\n", 2);
                   free(prompt);
                   return NULL;
           }
           if (getenv("DISPLAY") == NULL ||
               (askpass = getenv("SSH_ASKPASS")) == NULL || *askpass == '\0') {
                   debug3("%s: cannot notify", __func__);
                   free(prompt);
                   return NULL;
           }
           osigchld = signal(SIGCHLD, SIG_DFL);
           if ((pid = fork()) == -1) {
                   error("%s: fork: %s", __func__, strerror(errno));
                   signal(SIGCHLD, osigchld);
                   free(prompt);
                   return NULL;
           }
           if (pid == 0) {
                   if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1)
                           fatal("%s: open %s", __func__, strerror(errno));
                   if (dup2(devnull, STDIN_FILENO) == -1 ||
                       dup2(devnull, STDOUT_FILENO) == -1)
                           fatal("%s: dup2: %s", __func__, strerror(errno));
                   closefrom(STDERR_FILENO + 1);
                   setenv("SSH_ASKPASS_PROMPT", "none", 1); /* hint to UI */
                   execlp(askpass, askpass, prompt, (char *)NULL);
                   fatal("%s: exec(%s): %s", __func__, askpass, strerror(errno));
                   /* NOTREACHED */
           }
           if ((ret = calloc(1, sizeof(*ret))) == NULL) {
                   kill(pid, SIGTERM);
                   fatal("%s: calloc failed", __func__);
           }
           ret->pid = pid;
           ret->osigchld = osigchld;
           free(prompt);
           return ret;
   }
   
   void
   notify_complete(struct notifier_ctx *ctx)
   {
           int ret;
   
           if (ctx == NULL || ctx->pid <= 0) {
                   free(ctx);
                   return;
           }
           kill(ctx->pid, SIGTERM);
           while ((ret = waitpid(ctx->pid, NULL, 0)) == -1) {
                   if (errno != EINTR)
                           break;
           }
           if (ret == -1)
                   fatal("%s: waitpid: %s", __func__, strerror(errno));
           signal(SIGCHLD, ctx->osigchld);
           free(ctx);
   }

Legend:
Removed from v.1.54  
changed lines
  Added in v.1.55