Справочник по консольным командам Toybox для Android 12


  Ver.0.8.4     Ver.0.8.9     Pending  

Путь: Toys/Other, команды версии: Ver.4     Ver.9


timeout

Комментарии в файле timeout.c :

usage: timeout [-i] [-k DURATION] [-s SIGNAL] DURATION COMMAND...

Запустите командную строку как дочерний процесс, отправив дочернему сигналу, если команда не завершается достаточно скоро. DURATION может быть десятичной дробью. Необязательный суффикс может быть «м». (минуты), «ч» (часы), «д» (дни) или «с» (секунды, по умолчанию).
  • -i Уничтожать только при бездействии (тайм-аут перезапуска, когда команда производит вывод)
  • -k Отправлять сигнал KILL, если дочерний процесс все еще работает так долго после первого сигнала
  • -s Отправлять указанный сигнал (по умолчанию TERM)
  • -v Verbose
  • --foreground Не создавать новую группу процессов
  • --preserve-status Выход со статусом завершения дочернего процесса

  • usage: timeout [-i] [-k DURATION] [-s SIGNAL] DURATION COMMAND...

    Run command line as a child process, sending child a signal if the command doesn't exit soon enough. DURATION can be a decimal fraction. An optional suffix can be "m" (minutes), "h" (hours), "d" (days), or "s" (seconds, the default).
  • -i Only kill for inactivity (restart timeout when command produces output)
  • -k Send KILL signal if child still running this long after first signal
  • -s Send specified signal (default TERM)
  • -v Verbose
  • --foreground Don't create new process group
  • --preserve-status Exit with the child's exit status

  • Исходный текст в файле timeout.c

    #define FOR_timeout
    #include "toys.h"
    
    GLOBALS(
      char *s, *k;
    
      struct pollfd pfd;
      sigjmp_buf sj;
      int fds[2], pid;
    )
    
    static void handler(int sig)
    {
      siglongjmp(TT.sj, 1);
    }
    
    static long nantomil(struct timespec *ts)
    {
      return ts->tv_sec*1000+ts->tv_nsec/1000000;
    }
    
    static void callback(char *argv[])
    {
      xsignal(SIGCHLD, SIG_DFL);
      if (!FLAG(foreground)) setpgid(0, 0);
    }
    
    void timeout_main(void)
    {
      int ii, ms, nextsig = SIGTERM;
      struct timespec tts, kts;
    
      // Use same ARGFAIL value for any remaining parsing errors
      toys.exitval = 125;
      xparsetimespec(*toys.optargs, &tts);
      if (TT.k) xparsetimespec(TT.k, &kts);
      if (TT.s && -1==(nextsig = sig_to_num(TT.s))) error_exit("bad -s: '%s'",TT.s);
    
      toys.exitval = 0;
      TT.pfd.events = POLLIN;
      TT.fds[1] = -1;
      if (sigsetjmp(TT.sj, 1)) goto done;
      xsignal_flags(SIGCHLD, handler, SA_NOCLDSTOP);
    
      TT.pid = xpopen_setup(toys.optargs+1, FLAG(i) ? TT.fds : 0, callback);
      xsignal(SIGTTIN, SIG_IGN);
      xsignal(SIGTTOU, SIG_IGN);
      xsignal(SIGTSTP, SIG_IGN);
      if (!FLAG(i)) xpipe(TT.fds);
      TT.pfd.fd = TT.fds[1];
      ms = nantomil(&tts);
      for (;;) {
        if (1 != xpoll(&TT.pfd, 1, ms)) {
          if (FLAG(v))
            perror_msg("sending signal %s to command %s", num_to_sig(nextsig),
              toys.optargs[1]);
          toys.exitval = (nextsig==9) ? 137 : 124;
          kill(FLAG(foreground) ? TT.pid : -TT.pid, nextsig);
          if (!TT.k || nextsig==SIGKILL) break;
          nextsig = SIGKILL;
          ms = nantomil(&kts);
    
          continue;
        }
        if (TT.pfd.revents&POLLIN) {
          errno = 0;
          if (1>(ii = read(TT.fds[1], toybuf, sizeof(toybuf)))) {
            if (errno==EINTR) continue;
            break;
          }
          writeall(1, toybuf, ii);
        }
        if (TT.pfd.revents&POLLHUP) break;
      }
    done:
      xsignal(SIGCHLD, SIG_DFL);
      ii = xpclose_both(TT.pid, TT.fds);
    
      if (FLAG(preserve_status) || !toys.exitval) toys.exitval = ii;
    }