I found myself doing something like this alot:

$ some-program-that-changes-file-foo foo > foo.tmp
$ mv foo.tmp foo

Frankly that's kind of annoying.  I wrote a little utility called dcat
which allows you to do this:

$ some-program-that-changes-file-foo foo | dcat foo

Since tee has similar behavior (well, more similar than straight cat), I
implemented this behavior when using the -d flag.

I've attached the patch.  I hope that you find it useful!

-- 
Peter D. Kovacs <[EMAIL PROTECTED]>
--- tee.c.orig  Wed Mar 13 16:20:50 2002
+++ tee.c       Wed Mar 13 16:21:19 2002
@@ -15,7 +15,7 @@
    along with this program; if not, write to the Free Software Foundation,
    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
-/* Mike Parker, Richard M. Stallman, and David MacKenzie */
+/* Mike Parker, Richard M. Stallman, David MacKenzie, and Peter Kovacs */
 
 #include <config.h>
 #include <stdio.h>
@@ -30,7 +30,7 @@
 /* The official name of this program (e.g., no `g' prefix).  */
 #define PROGRAM_NAME "tee"
 
-#define AUTHORS "Mike Parker, Richard M. Stallman, and David MacKenzie"
+#define AUTHORS "Mike Parker, Richard M. Stallman, David MacKenzie and Peter Kovacs"
 
 int full_write ();
 
@@ -42,6 +42,9 @@
 /* If nonzero, ignore interrupts. */
 static int ignore_interrupts;
 
+/* if nonzero, delay the output */
+static int delay;
+
 /* The name that this program was run with. */
 char *program_name;
 
@@ -49,6 +52,7 @@
 {
   {"append", no_argument, NULL, 'a'},
   {"ignore-interrupts", no_argument, NULL, 'i'},
+  {"delay", no_argument, NULL, 'd'},
   {GETOPT_HELP_OPTION_DECL},
   {GETOPT_VERSION_OPTION_DECL},
   {NULL, 0, NULL, 0}
@@ -68,6 +72,7 @@
 \n\
   -a, --append              append to the given FILEs, do not overwrite\n\
   -i, --ignore-interrupts   ignore interrupt signals\n\
+  -d, --delay               delay writing to output file\n\
       --help                display this help and exit\n\
       --version             output version information and exit\n\
 "));
@@ -91,8 +96,9 @@
 
   append = 0;
   ignore_interrupts = 0;
+  delay = 0;
 
-  while ((optc = getopt_long (argc, argv, "ai", long_options, NULL)) != -1)
+  while ((optc = getopt_long (argc, argv, "aid", long_options, NULL)) != -1)
     {
       switch (optc)
        {
@@ -107,6 +113,10 @@
          ignore_interrupts = 1;
          break;
 
+       case 'd':
+         delay = 1;
+         break;
+
        case_GETOPT_HELP_CHAR;
 
        case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
@@ -167,14 +177,24 @@
   int bytes_read, i;
   int ret = 0;
   const char *mode_string = (append ? "a" : "w");
+  char **delay_files;
 
   descriptors = (FILE **) xmalloc ((nfiles + 1) * sizeof (descriptors[0]));
+  if ( delay )
+  {
+         delay_files = (char**)xmalloc( (nfiles + 1) * sizeof(delay_files[0]) );
+         for (i = nfiles; i >= 1; --i) {
+                 delay_files[i] = (char*)xmalloc( (strlen( files[i-1] ) + 6) * 
+sizeof(delay_files[0][0]) );
+                 sprintf(delay_files[i], "%sXXXXXX", files[i-1] );
+         }
+  }
 
   /* Move all the names `up' one in the argv array to make room for
      the entry for standard output.  This writes into argv[argc].  */
   for (i = nfiles; i >= 1; i--)
     files[i] = files[i - 1];
 
+
   SET_BINARY2 (0, 1);
 
   /* In the array of NFILES + 1 descriptors, make
@@ -185,6 +205,17 @@
 
   for (i = 1; i <= nfiles; i++)
     {
+                if ( delay ) {
+                        int fd = mkstemp( delay_files[i] );
+                        if ( fd < 0 || (descriptors[i] = fdopen( fd, mode_string )) 
+== NULL) {
+                                error (0, errno, "%s", files[i]);
+                                ret = 1;
+                        } else {
+                                SETVBUF (descriptors[i], NULL, _IONBF, 0);
+                                SET_BINARY (fileno (descriptors[i]));
+                        }
+                } else {
+
       descriptors[i] = fopen (files[i], mode_string);
       if (descriptors[i] == NULL)
        {
@@ -197,6 +228,7 @@
          SET_BINARY (fileno (descriptors[i]));
        }
     }
+    }
 
   while (1)
     {
@@ -224,15 +256,25 @@
     }
 
   /* Close the files, but not standard output.  */
-  for (i = 1; i <= nfiles; i++)
+  for (i = 1; i <= nfiles; i++) {
     if (descriptors[i] != NULL
        && (ferror (descriptors[i]) || fclose (descriptors[i]) == EOF))
       {
        error (0, errno, "%s", files[i]);
        ret = 1;
       }
+        if ( delay ) {
+        if ( rename( delay_files[i], files[i] ) ) {
+                error(0, errno, "%s", files[i] );
+                ret = 1;
+        }
+        free( delay_files[i] );
+        }
+  }
 
   free (descriptors);
+  if ( delay ) 
+         free( delay_files );
 
   return ret;
 }

Reply via email to