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

Diff for /src/usr.bin/tmux/job.c between version 1.55 and 1.56

version 1.55, 2019/06/28 13:35:05 version 1.56, 2020/03/19 13:43:18
Line 25 
Line 25 
 #include <stdlib.h>  #include <stdlib.h>
 #include <string.h>  #include <string.h>
 #include <unistd.h>  #include <unistd.h>
   #include <util.h>
   
 #include "tmux.h"  #include "tmux.h"
   
Line 69 
Line 70 
 struct job *  struct job *
 job_run(const char *cmd, struct session *s, const char *cwd,  job_run(const char *cmd, struct session *s, const char *cwd,
     job_update_cb updatecb, job_complete_cb completecb, job_free_cb freecb,      job_update_cb updatecb, job_complete_cb completecb, job_free_cb freecb,
     void *data, int flags)      void *data, int flags, int sx, int sy)
 {  {
         struct job      *job;          struct job      *job;
         struct environ  *env;          struct environ  *env;
         pid_t            pid;          pid_t            pid;
         int              nullfd, out[2];          int              nullfd, out[2], master;
         const char      *home;          const char      *home;
         sigset_t         set, oldset;          sigset_t         set, oldset;
           struct winsize   ws;
   
         if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, out) != 0)  
                 return (NULL);  
         log_debug("%s: cmd=%s, cwd=%s", __func__, cmd, cwd == NULL ? "" : cwd);  
   
         /*          /*
          * Do not set TERM during .tmux.conf, it is nice to be able to use           * Do not set TERM during .tmux.conf, it is nice to be able to use
          * if-shell to decide on default-terminal based on outside TERM.           * if-shell to decide on default-terminal based on outside TERM.
Line 90 
Line 88 
   
         sigfillset(&set);          sigfillset(&set);
         sigprocmask(SIG_BLOCK, &set, &oldset);          sigprocmask(SIG_BLOCK, &set, &oldset);
         switch (pid = fork()) {  
           if (flags & JOB_PTY) {
                   memset(&ws, 0, sizeof ws);
                   ws.ws_col = sx;
                   ws.ws_row = sy;
                   pid = fdforkpty(ptm_fd, &master, NULL, NULL, &ws);
           } else {
                   if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, out) != 0)
                           goto fail;
                   pid = fork();
           }
           log_debug("%s: cmd=%s, cwd=%s", __func__, cmd, cwd == NULL ? "" : cwd);
   
           switch (pid) {
         case -1:          case -1:
                 sigprocmask(SIG_SETMASK, &oldset, NULL);                  if (~flags & JOB_PTY) {
                 environ_free(env);                          close(out[0]);
                 close(out[0]);                          close(out[1]);
                 close(out[1]);                  }
                 return (NULL);                  goto fail;
         case 0:          case 0:
                 proc_clear_signals(server_proc, 1);                  proc_clear_signals(server_proc, 1);
                 sigprocmask(SIG_SETMASK, &oldset, NULL);                  sigprocmask(SIG_SETMASK, &oldset, NULL);
Line 109 
Line 120 
                 environ_push(env);                  environ_push(env);
                 environ_free(env);                  environ_free(env);
   
                 if (dup2(out[1], STDIN_FILENO) == -1)                  if (~flags & JOB_PTY) {
                         fatal("dup2 failed");                          if (dup2(out[1], STDIN_FILENO) == -1)
                 if (dup2(out[1], STDOUT_FILENO) == -1)                                  fatal("dup2 failed");
                         fatal("dup2 failed");                          if (dup2(out[1], STDOUT_FILENO) == -1)
                 if (out[1] != STDIN_FILENO && out[1] != STDOUT_FILENO)                                  fatal("dup2 failed");
                         close(out[1]);                          if (out[1] != STDIN_FILENO && out[1] != STDOUT_FILENO)
                 close(out[0]);                                  close(out[1]);
                           close(out[0]);
   
                 nullfd = open(_PATH_DEVNULL, O_RDWR, 0);                          nullfd = open(_PATH_DEVNULL, O_RDWR, 0);
                 if (nullfd == -1)                          if (nullfd == -1)
                         fatal("open failed");                                  fatal("open failed");
                 if (dup2(nullfd, STDERR_FILENO) == -1)                          if (dup2(nullfd, STDERR_FILENO) == -1)
                         fatal("dup2 failed");                                  fatal("dup2 failed");
                 if (nullfd != STDERR_FILENO)                          if (nullfd != STDERR_FILENO)
                         close(nullfd);                                  close(nullfd);
                   }
                 closefrom(STDERR_FILENO + 1);                  closefrom(STDERR_FILENO + 1);
   
                 execl(_PATH_BSHELL, "sh", "-c", cmd, (char *) NULL);                  execl(_PATH_BSHELL, "sh", "-c", cmd, (char *) NULL);
Line 133 
Line 145 
   
         sigprocmask(SIG_SETMASK, &oldset, NULL);          sigprocmask(SIG_SETMASK, &oldset, NULL);
         environ_free(env);          environ_free(env);
         close(out[1]);  
   
         job = xmalloc(sizeof *job);          job = xmalloc(sizeof *job);
         job->state = JOB_RUNNING;          job->state = JOB_RUNNING;
Line 150 
Line 161 
         job->freecb = freecb;          job->freecb = freecb;
         job->data = data;          job->data = data;
   
         job->fd = out[0];          if (~flags & JOB_PTY) {
                   close(out[1]);
                   job->fd = out[0];
           } else
                   job->fd = master;
         setblocking(job->fd, 0);          setblocking(job->fd, 0);
   
         job->event = bufferevent_new(job->fd, job_read_callback,          job->event = bufferevent_new(job->fd, job_read_callback,
Line 161 
Line 176 
   
         log_debug("run job %p: %s, pid %ld", job, job->cmd, (long) job->pid);          log_debug("run job %p: %s, pid %ld", job, job->cmd, (long) job->pid);
         return (job);          return (job);
   
   fail:
           sigprocmask(SIG_SETMASK, &oldset, NULL);
           environ_free(env);
           return (NULL);
 }  }
   
 /* Kill and free an individual job. */  /* Kill and free an individual job. */
Line 209 
Line 229 
         log_debug("job write %p: %s, pid %ld, output left %zu", job, job->cmd,          log_debug("job write %p: %s, pid %ld, output left %zu", job, job->cmd,
             (long) job->pid, len);              (long) job->pid, len);
   
         if (len == 0) {          if (len == 0 && (~job->flags & JOB_KEEPWRITE)) {
                 shutdown(job->fd, SHUT_WR);                  shutdown(job->fd, SHUT_WR);
                 bufferevent_disable(job->event, EV_WRITE);                  bufferevent_disable(job->event, EV_WRITE);
         }          }

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