bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#18621: [BUG] wc -c incorrectly counts bytes in /sys


From: Pádraig Brady
Subject: bug#18621: [BUG] wc -c incorrectly counts bytes in /sys
Date: Fri, 03 Oct 2014 17:48:20 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130110 Thunderbird/17.0.2

On 10/03/2014 03:47 PM, George Shuklin wrote:
> There is many sysfs (linux) attributes which reported as '4k files' but 
> contains just a few bytes.
> 
> wc file and wc -c shows different sizes.
> 
> Example:
> 
> $cat /sys/kernel/vmcoreinfo
> 1b74c00 1024
> 
> $hexdump -Cv /sys/kernel/vmcoreinfo
> 00000000  31 62 37 34 63 30 30 20  31 30 32 34 0a           |1b74c00 1024.|
> 0000000d
> 
> $ls -la /sys/kernel/vmcoreinfo
> -r--r--r-- 1 root root 4096 Oct  3 17:40 /sys/kernel/vmcoreinfo
> 
> 
> Here wc output:
> 
> $ wc /sys/kernel/vmcoreinfo
>    1    2   13 /sys/kernel/vmcoreinfo
> 
> and wc -c:
> 
> $ wc -c /sys/kernel/vmcoreinfo
> 4096 /sys/kernel/vmcoreinfo
> 
> 4096 is not 13, and manual page for wc says that third number is byte count.
> 
> I think problem is in  cnt(const char *file)  function:
> 
>     if (dochar || domulti) {
>         if (fstat(fd, &sb)) {
>             warn("%s: fstat", file);
>             (void)close(fd);
>             return (1);
>         }
>         if (S_ISREG(sb.st_mode)) {
>             (void)printf(" %7lld", (long long)sb.st_size);
>             tcharct += sb.st_size;
>             (void)close(fd);
>             return (0);
>         }
>     }

I'm not sure where the above code comes from,
by coreutils trunk has the same behavior with these files.
We could avoid it with the following patch.
Note in the case where "real" small files don't
take up space in the file system, this will involve a redundant read,
however that will only be the case for small files so shouldn't
be problematic.

thanks,
Pádraig.

diff --git a/src/wc.c b/src/wc.c
index 1ff007d..bf1ce76 100644
--- a/src/wc.c
+++ b/src/wc.c
@@ -235,6 +235,7 @@ wc (int fd, char const *file_x, struct fstatus *fstatus)
         fstatus->failed = fstat (fd, &fstatus->st);

       if (! fstatus->failed && S_ISREG (fstatus->st.st_mode)
+          && fstatus->st.st_blocks
           && (current_pos = lseek (fd, 0, SEEK_CUR)) != -1
           && (end_pos = lseek (fd, 0, SEEK_END)) != -1)
         {






reply via email to

[Prev in Thread] Current Thread [Next in Thread]