::  Posts  ::  RSS  ::  ◂◂RSS  ::  Contact

Self Redirection

January 28th, 2012
tech  [html]
Trying to append a file to another, I was surprised when the terminal just sat there, taking seconds for something that should have been instant. When I canceled the operation I found that the file I was trying to append to hadn't changed and the original file had ballooned to several megabytes. Looking back, I had redirected a file to itself:
  $ cat file1 >> file1 # should have been file2
You can try this yourself, but be prepared to hit Ctrl+C if it isn't instant:
   $ echo "abc" > tmp.txt
   $ cat tmp.txt >> tmp.txt
With BSD cat, as I have on my mac, this just sits there, filling up the disk at around 2MB/s. With GNU cat, on the server where I read email, I get:
   cat: tmp.txt: input file is output file
It's even smart enough to detect hardlinks:
   $ echo "abc" > tmp.txt
   $ ln tmp.txt tmp2.txt
   $ cat tmp.txt &gt> tmp2.txt
   cat: tmp.txt: input file is output file
The code for this in GNU cat, unchanged except for whitespace since at least 1992-11-08 when it was first put under source control, is:
   /* Input file can be output file for non-regular files.
      fstat on pipes returns S_IFSOCK on some systems, S_IFIFO
      on others, so the checking should not be done for those types,
      and to allow things like cat < /dev/tty > /dev/tty, checking
      is not done for device files either. */

   if (S_ISREG (stat_buf.st_mode))
     {
       out_dev = stat_buf.st_dev;
       out_ino = stat_buf.st_ino;
     }
   else
     check_redirection = 0;

   ...

   /* Compare the device and i-node numbers of this input file with
      the corresponding values of the (output file associated with)
      stdout, and skip this input file if they coincide.  Input
      files cannot be redirected to themselves.  */

   if (check_redirection
       && stat_buf.st_dev == out_dev && stat_buf.st_ino == out_ino)
     {
       error (0, 0, "%s: input file is output file", infile);
       exit_stat = 1;
       goto contin;
     }
The reason hardlinks don't fool cat is that it checks the device and inode values, which all hardlinks to a file will have the same:
   $ echo "abc" > tmp.txt
   $ ln tmp.txt tmp2.txt
   $ stat tmp.txt | grep Inode
   Device: 803h/2051dInode: 18645001    Links: 2
   $ $ stat tmp2.txt | grep Inode
   Device: 803h/2051dInode: 18645001    Links: 2

Comment via: google plus, facebook

Recent posts on blogs I like:

Pieces of time

My friend used to have two ‘days’ each day, with a nap between—in the afternoon, he would get up and plan his day with optimism, whatever happened a few hours before washed away. Another friend recently suggested to me thinking … Continue reading →

via Meteuphoric November 11, 2019

Mauerfall

The Berlin Wall fell 30 years ago. I feel weird about where I’m writing this post from. I was expecting to be writing this from Berlin, after visiting the commemorations. But I’m visiting Boston (and New York) right now and the connotation of talking abou…

via Pedestrian Observations November 10, 2019

Wild animal welfare in Hans Christian Andersen

Continuing the theme of wild animal suffering in children’s lit… Hans Christian Andersen’s stories involve a lot of suffering of both human and animal varieties. “The Ugly Duckling” takes a brief detour from describing the duckling’s repeated social humil…

via The whole sky November 7, 2019

more     (via openring)

More Posts:


  ::  Posts  ::  RSS  ::  ◂◂RSS  ::  Contact