GNU bug report logs - #19508
[PATCH] diff: compare major, minor numbers of block/character special files

Previous Next

Package: diffutils;

Reported by: Ondřej Svoboda <ondrej <at> svobodasoft.cz>

Date: Sun, 4 Jan 2015 21:24:02 UTC

Severity: normal

Tags: patch

To reply to this bug, email your comments to 19508 AT debbugs.gnu.org.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-diffutils <at> gnu.org:
bug#19508; Package diffutils. (Sun, 04 Jan 2015 21:24:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Ondřej Svoboda <ondrej <at> svobodasoft.cz>:
New bug report received and forwarded. Copy sent to bug-diffutils <at> gnu.org. (Sun, 04 Jan 2015 21:24:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Ondřej Svoboda <ondrej <at> svobodasoft.cz>
To: bug-diffutils <at> gnu.org
Subject: [PATCH] diff: compare major, minor numbers of block/character special
 files
Date: Sun, 04 Jan 2015 21:51:50 +0100
This deals with situation such as

  File dev1/block1 is a block special file while file dev2/block1 is
  a block special file

in case the major and minor numbers are identical.
If stat.st_rdev does not match, a message is given:

  Block special files dev1/block1 and dev2/block1 differ: 1,2 (3,2)
---
 src/diff.c | 23 +++++++++++++++++++++++
 src/diff.h |  1 +
 src/util.c |  9 +++++++++
 3 files changed, 33 insertions(+)

diff --git a/src/diff.c b/src/diff.c
index ff28377..a3e1b6f 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -1276,6 +1276,29 @@ compare_files (struct comparison const *parent,
 	      status = EXIT_FAILURE;
 	    }
 	}
+      else if ((S_ISBLK (cmp.file[0].stat.st_mode)
+	        && S_ISBLK (cmp.file[1].stat.st_mode))
+	       || (S_ISCHR (cmp.file[0].stat.st_mode)
+	           && S_ISCHR (cmp.file[1].stat.st_mode)))
+	{
+	  if (cmp.file[0].stat.st_rdev != cmp.file[1].stat.st_rdev)
+	    {
+	      char major_minor0[20], major_minor1[20];
+	      format_major_minor (major_minor0, cmp.file[0].stat.st_rdev);
+	      format_major_minor (major_minor1, cmp.file[1].stat.st_rdev);
+
+	      const char *message = S_ISBLK (cmp.file[0].stat.st_mode) ?
+			"Block special files %s and %s differ: %s (%s)\n" :
+			"Character special files %s and %s differ: %s (%s)\n";
+	      message5 (message,
+			file_label[0] ? file_label[0] : cmp.file[0].name,
+			file_label[1] ? file_label[1] : cmp.file[1].name,
+			major_minor0, major_minor1);
+
+	      /* This is a difference.  */
+	      status = EXIT_FAILURE;
+	    }
+	}
       else
 	{
 	  /* We have two files that are not to be compared.  */
diff --git a/src/diff.h b/src/diff.h
index 465e4bc..098e75f 100644
--- a/src/diff.h
+++ b/src/diff.h
@@ -390,3 +390,4 @@ extern void print_script (struct change *, struct 
change * (*) (struct change *)
 extern void setup_output (char const *, char const *, bool);
 extern void translate_range (struct file_data const *, lin, lin,
                              long int *, long int *);
+extern void format_major_minor (char *buffer, const dev_t st_rdev);
diff --git a/src/util.c b/src/util.c
index 2d6d3fc..4773003 100644
--- a/src/util.c
+++ b/src/util.c
@@ -24,6 +24,7 @@
 #include <system-quote.h>
 #include <xalloc.h>
 #include "xvasprintf.h"
+#include <sys/types.h>
  char const pr_program[] = PR_PROGRAM;
 @@ -907,3 +908,11 @@ debug_script (struct change *sp)
    fflush (stderr);
 }
+
+/* Format a device number as major,minor. */
+
+void
+format_major_minor (char *buffer, const dev_t st_rdev)
+{
+  sprintf (buffer, "%u,%u", (major (st_rdev)), (minor (st_rdev)));
+}
-- 
2.2.1





Information forwarded to bug-diffutils <at> gnu.org:
bug#19508; Package diffutils. (Wed, 11 Feb 2015 23:41:01 GMT) Full text and rfc822 format available.

Message #8 received at 19508 <at> debbugs.gnu.org (full text, mbox):

From: Ondřej Svoboda <ondrej <at> svobodasoft.cz>
To: 19508 <at> debbugs.gnu.org, Paul Eggert <eggert <at> cs.ucla.edu>
Subject: Re: [bug-diffutils] bug#19508: [PATCH] diff: compare major, minor
 numbers of block/character special files
Date: Thu, 12 Feb 2015 00:40:15 +0100
Paul, this is the first patch in the series (and is succeeded by the 
fifo one), I am sorry for the confusion.

Could you please give it a look?

Thanks :-)
Ondra Svoboda

On 4.1.2015 21:51, Ondřej Svoboda wrote:
> This deals with situation such as
>
>   File dev1/block1 is a block special file while file dev2/block1 is
>   a block special file
>
> in case the major and minor numbers are identical.
> If stat.st_rdev does not match, a message is given:
>
>   Block special files dev1/block1 and dev2/block1 differ: 1,2 (3,2)
> ---
>  src/diff.c | 23 +++++++++++++++++++++++
>  src/diff.h |  1 +
>  src/util.c |  9 +++++++++
>  3 files changed, 33 insertions(+)
>
> diff --git a/src/diff.c b/src/diff.c
> index ff28377..a3e1b6f 100644
> --- a/src/diff.c
> +++ b/src/diff.c
> @@ -1276,6 +1276,29 @@ compare_files (struct comparison const *parent,
>            status = EXIT_FAILURE;
>          }
>      }
> +      else if ((S_ISBLK (cmp.file[0].stat.st_mode)
> +            && S_ISBLK (cmp.file[1].stat.st_mode))
> +           || (S_ISCHR (cmp.file[0].stat.st_mode)
> +               && S_ISCHR (cmp.file[1].stat.st_mode)))
> +    {
> +      if (cmp.file[0].stat.st_rdev != cmp.file[1].stat.st_rdev)
> +        {
> +          char major_minor0[20], major_minor1[20];
> +          format_major_minor (major_minor0, cmp.file[0].stat.st_rdev);
> +          format_major_minor (major_minor1, cmp.file[1].stat.st_rdev);
> +
> +          const char *message = S_ISBLK (cmp.file[0].stat.st_mode) ?
> +            "Block special files %s and %s differ: %s (%s)\n" :
> +            "Character special files %s and %s differ: %s (%s)\n";
> +          message5 (message,
> +            file_label[0] ? file_label[0] : cmp.file[0].name,
> +            file_label[1] ? file_label[1] : cmp.file[1].name,
> +            major_minor0, major_minor1);
> +
> +          /* This is a difference.  */
> +          status = EXIT_FAILURE;
> +        }
> +    }
>        else
>      {
>        /* We have two files that are not to be compared.  */
> diff --git a/src/diff.h b/src/diff.h
> index 465e4bc..098e75f 100644
> --- a/src/diff.h
> +++ b/src/diff.h
> @@ -390,3 +390,4 @@ extern void print_script (struct change *, struct 
> change * (*) (struct change *)
>  extern void setup_output (char const *, char const *, bool);
>  extern void translate_range (struct file_data const *, lin, lin,
>                               long int *, long int *);
> +extern void format_major_minor (char *buffer, const dev_t st_rdev);
> diff --git a/src/util.c b/src/util.c
> index 2d6d3fc..4773003 100644
> --- a/src/util.c
> +++ b/src/util.c
> @@ -24,6 +24,7 @@
>  #include <system-quote.h>
>  #include <xalloc.h>
>  #include "xvasprintf.h"
> +#include <sys/types.h>
>   char const pr_program[] = PR_PROGRAM;
>  @@ -907,3 +908,11 @@ debug_script (struct change *sp)
>     fflush (stderr);
>  }
> +
> +/* Format a device number as major,minor. */
> +
> +void
> +format_major_minor (char *buffer, const dev_t st_rdev)
> +{
> +  sprintf (buffer, "%u,%u", (major (st_rdev)), (minor (st_rdev)));
> +}





Information forwarded to bug-diffutils <at> gnu.org:
bug#19508; Package diffutils. (Sat, 12 Mar 2016 13:57:02 GMT) Full text and rfc822 format available.

Message #11 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Ondřej Svoboda <ondrej <at> svobodasoft.cz>
To: bug-diffutils <at> gnu.org
Subject: [bug-diffutils] bug#19508: [PATCH] diff: compare major, minor numbers
 of block/character special files
Date: Sat, 12 Mar 2016 14:55:56 +0100
[Message part 1 (text/plain, inline)]
Hi everybody,

I rebased the patch on current master and tested it (as root) like this:

# mkdir /tmp/a /tmp/b
# mknod /tmp/a/block1 b 1 2; mknod /tmp/b/block1 b 1 2
# mknod /tmp/a/block2 b 2 3; mknod /tmp/b/block2 b 2 4
# mknod /tmp/a/block3 b 3 4; mknod /tmp/b/block3 b 5 4
# mknod /tmp/a/char1 c 1 2; mknod /tmp/b/char1 c 1 2
# mknod /tmp/a/char2 c 2 3; mknod /tmp/b/char2 c 2 4
# mknod /tmp/a/char3 c 3 4; mknod /tmp/b/char3 c 5 4

# LC_ALL=C ls -l /tmp/a
total 0
brw-r--r-- 1 root root 1, 2 Mar 12 14:51 block1
brw-r--r-- 1 root root 2, 3 Mar 12 14:51 block2
brw-r--r-- 1 root root 3, 4 Mar 12 14:51 block3
crw-r--r-- 1 root root 1, 2 Mar 12 14:51 char1
crw-r--r-- 1 root root 2, 3 Mar 12 14:51 char2
crw-r--r-- 1 root root 3, 4 Mar 12 14:51 char3

# LC_ALL=C ls -l /tmp/b
total 0
brw-r--r-- 1 root root 1, 2 Mar 12 14:51 block1
brw-r--r-- 1 root root 2, 4 Mar 12 14:51 block2
brw-r--r-- 1 root root 5, 4 Mar 12 14:51 block3
crw-r--r-- 1 root root 1, 2 Mar 12 14:51 char1
crw-r--r-- 1 root root 2, 4 Mar 12 14:51 char2
crw-r--r-- 1 root root 5, 4 Mar 12 14:51 char3

# LC_ALL=C diff -s -r /tmp/a /tmp/b
Files /tmp/a/block1 and /tmp/b/block1 are identical
File /tmp/a/block2 is a block special file while file /tmp/b/block2 is a 
block special file
File /tmp/a/block3 is a block special file while file /tmp/b/block3 is a 
block special file
Files /tmp/a/char1 and /tmp/b/char1 are identical
File /tmp/a/char2 is a character special file while file /tmp/b/char2 is 
a character special file
File /tmp/a/char3 is a character special file while file /tmp/b/char3 is 
a character special file

# LC_ALL=C /usr/local/bin/diff -s -r /tmp/a /tmp/b
Files /tmp/a/block1 and /tmp/b/block1 are identical
Block special files /tmp/a/block2 and /tmp/b/block2 differ: 2,3 (2,4)
Block special files /tmp/a/block3 and /tmp/b/block3 differ: 3,4 (5,4)
Files /tmp/a/char1 and /tmp/b/char1 are identical
Character special files /tmp/a/char2 and /tmp/b/char2 differ: 2,3 (2,4)
Character special files /tmp/a/char3 and /tmp/b/char3 differ: 3,4 (5,4)

The reason why diff compared block1 as identical perhaps because it 
descended to diff_2_files, I would know if I stepped through the code 
which I currently don't have much time to do.

Please share your comments!

Cheers,
Ondra
[0001-diff-compare-major-minor-numbers-of-block-character-.patch (text/x-patch, attachment)]

Information forwarded to bug-diffutils <at> gnu.org:
bug#19508; Package diffutils. (Sat, 12 Mar 2016 14:18:01 GMT) Full text and rfc822 format available.

Message #14 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Ondřej Svoboda <ondrej <at> svobodasoft.cz>
To: bug-diffutils <at> gnu.org
Subject: Re: [bug-diffutils] bug#19508: bug#19508: [PATCH] diff: compare
 major, minor numbers of block/character special files
Date: Sat, 12 Mar 2016 15:16:49 +0100
Please see the follow-up on testing below.

On 12.3.2016 14:55, Ondřej Svoboda wrote:
> Hi everybody,
>
> I rebased the patch on current master and tested it (as root) like this:
>
> # mkdir /tmp/a /tmp/b
> # mknod /tmp/a/block1 b 1 2; mknod /tmp/b/block1 b 1 2
> # mknod /tmp/a/block2 b 2 3; mknod /tmp/b/block2 b 2 4
> # mknod /tmp/a/block3 b 3 4; mknod /tmp/b/block3 b 5 4
> # mknod /tmp/a/char1 c 1 2; mknod /tmp/b/char1 c 1 2
> # mknod /tmp/a/char2 c 2 3; mknod /tmp/b/char2 c 2 4
> # mknod /tmp/a/char3 c 3 4; mknod /tmp/b/char3 c 5 4
>
> # LC_ALL=C ls -l /tmp/a
> total 0
> brw-r--r-- 1 root root 1, 2 Mar 12 14:51 block1
> brw-r--r-- 1 root root 2, 3 Mar 12 14:51 block2
> brw-r--r-- 1 root root 3, 4 Mar 12 14:51 block3
> crw-r--r-- 1 root root 1, 2 Mar 12 14:51 char1
> crw-r--r-- 1 root root 2, 3 Mar 12 14:51 char2
> crw-r--r-- 1 root root 3, 4 Mar 12 14:51 char3
>
> # LC_ALL=C ls -l /tmp/b
> total 0
> brw-r--r-- 1 root root 1, 2 Mar 12 14:51 block1
> brw-r--r-- 1 root root 2, 4 Mar 12 14:51 block2
> brw-r--r-- 1 root root 5, 4 Mar 12 14:51 block3
> crw-r--r-- 1 root root 1, 2 Mar 12 14:51 char1
> crw-r--r-- 1 root root 2, 4 Mar 12 14:51 char2
> crw-r--r-- 1 root root 5, 4 Mar 12 14:51 char3
>
> # LC_ALL=C diff -s -r /tmp/a /tmp/b
> Files /tmp/a/block1 and /tmp/b/block1 are identical
> File /tmp/a/block2 is a block special file while file /tmp/b/block2 is 
> a block special file
> File /tmp/a/block3 is a block special file while file /tmp/b/block3 is 
> a block special file
> Files /tmp/a/char1 and /tmp/b/char1 are identical
> File /tmp/a/char2 is a character special file while file /tmp/b/char2 
> is a character special file
> File /tmp/a/char3 is a character special file while file /tmp/b/char3 
> is a character special file
>
> # LC_ALL=C /usr/local/bin/diff -s -r /tmp/a /tmp/b
> Files /tmp/a/block1 and /tmp/b/block1 are identical
> Block special files /tmp/a/block2 and /tmp/b/block2 differ: 2,3 (2,4)
> Block special files /tmp/a/block3 and /tmp/b/block3 differ: 3,4 (5,4)
> Files /tmp/a/char1 and /tmp/b/char1 are identical
> Character special files /tmp/a/char2 and /tmp/b/char2 differ: 2,3 (2,4)
> Character special files /tmp/a/char3 and /tmp/b/char3 differ: 3,4 (5,4)
>
> The reason why diff compared block1 as identical perhaps because it 
> descended to diff_2_files, I would know if I stepped through the code 
> which I currently don't have much time to do.

# touch /tmp/b/*

# LC_ALL=C ls -l /tmp/b
total 0
brw-r--r-- 1 root root 1, 2 Mar 12 15:09 block1
brw-r--r-- 1 root root 2, 4 Mar 12 15:09 block2
brw-r--r-- 1 root root 5, 4 Mar 12 15:09 block3
crw-r--r-- 1 root root 1, 2 Mar 12 15:09 char1
crw-r--r-- 1 root root 2, 4 Mar 12 15:09 char2
crw-r--r-- 1 root root 5, 4 Mar 12 15:09 char3

# LC_ALL=C diff -s -r /tmp/a /tmp/b
File /tmp/a/block1 is a block special file while file /tmp/b/block1 is a 
block special file
File /tmp/a/block2 is a block special file while file /tmp/b/block2 is a 
block special file
File /tmp/a/block3 is a block special file while file /tmp/b/block3 is a 
block special file
File /tmp/a/char1 is a character special file while file /tmp/b/char1 is 
a character special file
File /tmp/a/char2 is a character special file while file /tmp/b/char2 is 
a character special file
File /tmp/a/char3 is a character special file while file /tmp/b/char3 is 
a character special file

# LC_ALL=C /usr/local/bin/diff -s -r /tmp/a /tmp/b :(
Files /tmp/a/block1 and /tmp/b/block1 are identical
Block special files /tmp/a/block2 and /tmp/b/block2 differ: 2,3 (2,4)
Block special files /tmp/a/block3 and /tmp/b/block3 differ: 3,4 (5,4)
Files /tmp/a/char1 and /tmp/b/char1 are identical
Character special files /tmp/a/char2 and /tmp/b/char2 differ: 2,3 (2,4)
Character special files /tmp/a/char3 and /tmp/b/char3 differ: 3,4 (5,4)

After changing the modification datetime, both block1 and char1 compared 
differently with diffutils 3.3-2 (on Arch Linux) while they were found 
to be the same with the patched diff from master.

> Please share your comments!
>
> Cheers,
> Ondra





This bug report was last modified 9 years and 96 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.