Anonymous avatar Anonymous committed 4352a68

`-t timeout`; fix #4, alternative solution re #2.

Adds new flag `-t timeout milliseconds`, to stop long-running vcprompt
invocatoins.

`vcprompt -t 20` is recommended usage.

TODO:

* respect -f in how the result should printed on a timeout job.

Comments (0)

Files changed (2)

     int show_revision;                  /* show current revision? */
     int show_unknown;                   /* show ? if unknown files? */
     int show_modified;                  /* show + if local changes? */
+    unsigned int timeout;               /* timeout in milliseconds*/
 } options_t;
 
 /* What we figured out by analyzing the working dir: info that
              result_t* (*get_info)(vccontext_t*));
 void
 free_context(vccontext_t* context);
-    
+
 result_t*
 init_result();
 
 #include <string.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <sys/time.h>
 #include <unistd.h>
 
+#include <signal.h>
+
 #include "common.h"
 #include "cvs.h"
 #include "git.h"
 void parse_args(int argc, char** argv, options_t* options)
 {
     int opt;
-    while ((opt = getopt(argc, argv, "hf:d")) != -1) {
+    char* timeoutstring;
+    while ((opt = getopt(argc, argv, "hf:dt:")) != -1) {
         switch (opt) {
             case 'f':
                 options->format = optarg;
             case 'd':
                 options->debug = 1;
                 break;
+            case 't':
+                options->timeout = strtol(optarg,&timeoutstring,10);
+                break;
             case 'h':
             default:
-                printf("usage: %s [-h] [-d] [-f FORMAT]\n", argv[0]);
+                printf("usage: %s [-h] [-d] [-t ms_timeout] [-f FORMAT]\n", argv[0]);
                 printf("FORMAT (default=\"%s\") may contain:\n%s",
                 DEFAULT_FORMAT,
                 " %b  show branch\n"
     }
 }
 
+
+/* The signal handler just clears the flag and re-enables itself.  */
+void
+exit_on_alarm (int sig)
+{
+    printf("[unknown:timeout]");
+    exit(1);
+}
+
+unsigned int
+msalarm (unsigned int milliseconds)
+{
+    struct itimerval old, new;
+    new.it_interval.tv_usec = 0;
+    new.it_interval.tv_sec = 0;
+    new.it_value.tv_usec = 1000 * (long int) milliseconds;
+    new.it_value.tv_sec =  0;
+    if (setitimer (ITIMER_REAL, &new, &old) < 0)
+        return 0;
+    else
+        return old.it_value.tv_sec;
+}
+
 int main(int argc, char** argv)
 {
+    /* Establish a handler for SIGALRM signals.  */
+    signal (SIGALRM, exit_on_alarm);
+
     char* format = getenv("VCPROMPT_FORMAT");
     if (format == NULL)
         format = DEFAULT_FORMAT;
         .show_unknown  = 0,
         .show_modified = 0,
     };
-
     parse_args(argc, argv, &options);
     parse_format(&options);
     set_options(&options);
 
+    if (options.timeout) {
+        debug("will timeout after %d ms", options.timeout);
+        msalarm (options.timeout);
+    } else {
+        debug("will never timeout");
+    }
+
     vccontext_t* contexts[] = {
         get_cvs_context(&options),
         get_git_context(&options),
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.