This might lead to false positive if the tar file is written to another device.
$ ~/.sbase/bin/tar cf /mnt/backup/test.tar .config ignoring '.config/zathura/zathurarc' $ find .config/zathura/zathurarc /mnt/backup/test.tar -printf "%i %D %p\n" 1259 2050 .config/zathura/zathurarc 1259 2081 /mnt/backup/test.tar Attached diff also checks st_dev, which ought to cover all cases. Regards, Lars. On 20/07-13, Roberto E. Vargas Caballero wrote: > This patch fixes this issue using the inode number of the tar > file. > > > > -- > Roberto E. Vargas Caballero > ---------------------------- > k...@shike2.com > http://www.shike2.com > From e5b989e7899c87f316597e6b8ed39adfa97959b2 Mon Sep 17 00:00:00 2001 > From: "Roberto E. Vargas Caballero" <k...@shike2.com> > Date: Sat, 20 Jul 2013 18:08:58 +0200 > Subject: [PATCH] Avoid infinite loop in tar > > When the tar file is written in one directory archived by tar > the function archive enters in an infinite loop due to de > tar file written. This patch avoid this case checking the > inode of the tar file before of adding it to the archive. > --- > tar.c | 10 ++++++++++ > 1 file changed, 10 insertions(+) > > diff --git a/tar.c b/tar.c > index 87b7236..0f3ce33 100644 > --- a/tar.c > +++ b/tar.c > @@ -47,6 +47,7 @@ static void c(char *); > static void xt(int (*)(char*, int, char[Blksiz])); > > static FILE *tarfile; > +static ino_t tarinode; > > static void > usage(void) > @@ -117,9 +118,14 @@ main(int argc, char *argv[]) > usage(); > > if(file) { > + struct stat st; > + > tarfile = fopen(file, (mode == 'c') ? "wb" : "rb"); > if(!tarfile) > eprintf("tar: open '%s':", file); > + if (lstat(file, &st) < 0) > + eprintf("tar: stat '%s':", file); > + tarinode = st.st_ino; > } else { > tarfile = (mode == 'c') ? stdout : stdin; > } > @@ -155,6 +161,10 @@ archive(const char* path, const struct stat* sta, int > type) > mode_t mode; > > lstat(path, &st); > + if (st.st_ino == tarinode) { > + fprintf(stderr, "ignoring '%s'\n", path); > + return 0; > + } > pw = getpwuid(st.st_uid); > gr = getgrgid(st.st_gid); > > -- > 1.8.3.2 >
--- tar-orig.c 2013-07-22 00:29:33.078595937 +0200 +++ tar.c 2013-07-22 00:30:41.786328335 +0200 @@ -48,6 +48,7 @@ static FILE *tarfile; static ino_t tarinode; +static dev_t tardev; static void usage(void) @@ -126,6 +127,7 @@ if (lstat(file, &st) < 0) eprintf("tar: stat '%s':", file); tarinode = st.st_ino; + tardev = st.st_dev; } else { tarfile = (mode == 'c') ? stdout : stdin; } @@ -161,7 +163,7 @@ mode_t mode; lstat(path, &st); - if (st.st_ino == tarinode) { + if (st.st_ino == tarinode && st.st_dev == tardev) { fprintf(stderr, "ignoring '%s'\n", path); return 0; }