]> Dogcows Code - chaz/tar/blobdiff - src/checkpoint.c
tar: don't assume O_NONBLOCK is benign on regular files
[chaz/tar] / src / checkpoint.c
index 5eaaea550cfa5e97d8695a6ae334e75b2caec2d7..a2896ab3d3cf1205ac7a7c411c77203e36fd4d0d 100644 (file)
@@ -21,7 +21,9 @@
 enum checkpoint_opcode
   {
     cop_dot,
+    cop_bell,
     cop_echo,
+    cop_ttyout,
     cop_sleep,
     cop_exec
   };
@@ -75,9 +77,11 @@ void
 checkpoint_compile_action (const char *str)
 {
   struct checkpoint_action *act;
-  
+
   if (strcmp (str, ".") == 0 || strcmp (str, "dot") == 0)
     alloc_action (cop_dot);
+  else if (strcmp (str, "bell") == 0)
+    alloc_action (cop_bell);
   else if (strcmp (str, "echo") == 0)
     alloc_action (cop_echo);
   else if (strncmp (str, "echo=", 5) == 0)
@@ -90,6 +94,11 @@ checkpoint_compile_action (const char *str)
       act = alloc_action (cop_exec);
       act->v.command = copy_string_unquote (str + 5);
     }
+  else if (strncmp (str, "ttyout=", 7) == 0)
+    {
+      act = alloc_action (cop_ttyout);
+      act->v.command = copy_string_unquote (str + 7);
+    }
   else if (strncmp (str, "sleep=", 6) == 0)
     {
       char *p;
@@ -110,14 +119,14 @@ checkpoint_finish_compile ()
     {
       if (!checkpoint_action)
        /* Provide a historical default */
-       checkpoint_compile_action ("echo"); 
+       checkpoint_compile_action ("echo");
     }
   else if (checkpoint_action)
     /* Otherwise, set default checkpoint rate */
     checkpoint_option = DEFAULT_CHECKPOINT;
 }
 
-char *
+static char *
 expand_checkpoint_string (const char *input, bool do_write, unsigned cpn)
 {
   const char *opstr = do_write ? gettext ("write") : gettext ("read");
@@ -138,7 +147,7 @@ expand_checkpoint_string (const char *input, bool do_write, unsigned cpn)
        case 'u':
          outlen += cpslen - 2;
          break;
-         
+
        case 's':
          outlen += opstrlen - 2;
        }
@@ -155,11 +164,11 @@ expand_checkpoint_string (const char *input, bool do_write, unsigned cpn)
            case 'u':
              op = stpcpy (op, cps);
              break;
-             
+
            case 's':
              op = stpcpy (op, opstr);
              break;
-             
+
            default:
              *op++ = '%';
              *op++ = *ip;
@@ -178,6 +187,7 @@ static void
 run_checkpoint_actions (bool do_write)
 {
   struct checkpoint_action *p;
+  FILE *tty = NULL;
 
   for (p = checkpoint_action; p; p = p->next)
     {
@@ -187,7 +197,17 @@ run_checkpoint_actions (bool do_write)
          fputc ('.', stdlis);
          fflush (stdlis);
          break;
-         
+
+       case cop_bell:
+         if (!tty)
+           tty = fopen ("/dev/tty", "w");
+         if (tty)
+           {
+             fputc ('\a', tty);
+             fflush (tty);
+           }
+         break;
+
        case cop_echo:
          {
            char *tmp;
@@ -212,11 +232,24 @@ run_checkpoint_actions (bool do_write)
            free (tmp);
          }
          break;
-         
+
+       case cop_ttyout:
+         if (!tty)
+           tty = fopen ("/dev/tty", "w");
+         if (tty)
+           {
+             char *tmp = expand_checkpoint_string (p->v.command, do_write,
+                                                   checkpoint);
+             fprintf (tty, "%s", tmp);
+             fflush (tty);
+             free (tmp);
+           }
+         break;
+
        case cop_sleep:
          sleep (p->v.time);
          break;
-         
+
        case cop_exec:
          sys_exec_checkpoint_script (p->v.command,
                                      archive_name_cursor[0],
@@ -224,6 +257,8 @@ run_checkpoint_actions (bool do_write)
          break;
        }
     }
+  if (tty)
+    fclose (tty);
 }
 
 void
@@ -231,5 +266,4 @@ checkpoint_run (bool do_write)
 {
   if (checkpoint_option && !(++checkpoint % checkpoint_option))
     run_checkpoint_actions (do_write);
-}  
-
+}
This page took 0.027171 seconds and 4 git commands to generate.