[7085] in Athena Bugs

home help back first fref pref prev next nref lref last post

/usr/athena/timeout

daemon@ATHENA.MIT.EDU (daemon@ATHENA.MIT.EDU)
Sun Feb 10 22:46:10 1991

To: bugs@ATHENA.MIT.EDU
Date: Sun, 10 Feb 91 22:46:02 EST
From: John Carr <jfc@ATHENA.MIT.EDU>


There are a number of problems with /usr/athena/timeout:

	. 10 second resolution

	. ignores application exit status

	. does not notice application exit due to signal

	. does not print reason for failure to fork or exec

	. timeout prints incorrect message if program exits after time
	has expired but before the next 10 second check

A remaining bug that might not be fixable: if the user is typing
cooked mode input, timeout does not notice it until the user hits
return.

*** timeout.c.orig	Fri Nov 16 15:48:13 1990
--- timeout.c	Sun Feb 10 22:40:23 1991
***************
*** 17,22 ****
--- 17,23 ----
  
  int app_pid;
  volatile int app_running;
+ int app_exit_status;
  
  
  main(argc, argv)
***************
*** 25,30 ****
--- 26,32 ----
  {
      int maxidle;
      char *name;
+     int ttl;
      struct stat stbuf;
      struct timeval now, start;
      void child(), wakeup();
***************
*** 46,55 ****
      switch (app_pid = fork()) {
      case 0:
  	execv(argv[0], argv);
! 	fprintf(stderr, "%s: failed to exec application %s\n", name, argv[0]);
  	exit(1);
      case -1:
! 	fprintf(stderr, "%s: failed to fork to create application\n", name);
  	exit(1);
      default:
  	break;
--- 48,57 ----
      switch (app_pid = fork()) {
      case 0:
  	execv(argv[0], argv);
! 	perror("timeout: can't exec application");
  	exit(1);
      case -1:
! 	perror("timeout: can't fork to exec application");
  	exit(1);
      default:
  	break;
***************
*** 57,76 ****
  
      gettimeofday(&start, NULL);
      /* wait for application to die or idle-time to be reached */
      while (app_running) {
! 	alarm(10);		/* sleep 10 seconds */
  	sigpause(0);
  	fstat(1, &stbuf);
  	gettimeofday(&now, NULL);
! 	/* only check idle time if we've been running at least that long */
! 	if (start.tv_sec + maxidle <= now.tv_sec &&
! 	    stbuf.st_atime + maxidle <= now.tv_sec) {
  	    fprintf(stderr, "\nMAX IDLE TIME REACHED.\n");
  	    kill(app_pid, SIGINT);
  	    exit(0);
  	}
      }
!     exit(0);
  }
  
  void child()
--- 59,82 ----
  
      gettimeofday(&start, NULL);
      /* wait for application to die or idle-time to be reached */
+     ttl = maxidle;
      while (app_running) {
! 	alarm(ttl);
  	sigpause(0);
+ 	if (!app_running)
+ 	    break;
  	fstat(1, &stbuf);
  	gettimeofday(&now, NULL);
! 	ttl = start.tv_sec + maxidle - now.tv_sec;
! 	if (ttl <= 0)
! 	    ttl = stbuf.st_atime + maxidle - now.tv_sec;
! 	if (ttl <= 0) {
  	    fprintf(stderr, "\nMAX IDLE TIME REACHED.\n");
  	    kill(app_pid, SIGINT);
  	    exit(0);
  	}
      }
!     exit(app_exit_status);
  }
  
  void child()
***************
*** 79,88 ****
      int pid;
  
      pid = wait3(&status, WNOHANG, 0);
!     if (pid != app_pid)
        return;
-     if (WIFEXITED(status))
        app_running = FALSE;
  }
  
  void wakeup()
--- 85,97 ----
      int pid;
  
      pid = wait3(&status, WNOHANG, 0);
!     if (pid != app_pid || WIFSTOPPED(status))
  	return;
      app_running = FALSE;
+     if (WIFEXITED(status))
+ 	app_exit_status = status.w_retcode;
+     else
+ 	app_exit_status = -status.w_termsig;
  }
  
  void wakeup()

home help back first fref pref prev next nref lref last post