[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: stat signed/unsigned
From: |
Pádraig Brady |
Subject: |
Re: stat signed/unsigned |
Date: |
Wed, 7 Jan 2009 11:14:57 +0000 |
User-agent: |
Thunderbird 2.0.0.6 (X11/20071008) |
Jim Meyering wrote:
> Pádraig Brady <address@hidden> wrote:
> ...
>>> That sounds like it could be rather invasive...
>>> >From an aesthetics/readability point of view, I'm not sure
>>> I like the idea of using ST_SIZE (st) in place of "st.st_size".
>> Well it would be more consistent as we already use ST_BLKSIZE etc.
>> There aren't many references to .st_size really.
>>
>>> More importantly, there are places in the code that compare stat.st_size
>>> against negative numbers (at least remove.c).
>> Yuk, so that code assumes that st_size will be always be signed,
>
> It's guaranteed that st_size's type is signed, since off_t is signed.
What I meant is that it assumes that st_size will never overflow.
> Using a macro to cast away such "known" signedness sounds
> dangerous.
I think it's safer to assume "known" unsignedness in this case?
>>> I've started down this clean-up-Wsign-compare-warnings road
>>> a few times, and inevitably end up concluding it's not worthwhile.
>> The current patch I have is 50 insertions(+), 37 deletions(-)
>> So for 13 new lines of code with no new casts I think it
>> probably is worth addressing.
>
> show the code ;-)
Current code is attached.
Before I commit though I need to fix also 6 files in lib/
Also I need to test on 64 bit, and with _FILE_OFFSET_BITS=32
cheers,
Pádraig.
>From b373082f939708182f75fa71d8bda813b26d71ef Mon Sep 17 00:00:00 2001
From: =?utf-8?q?P=C3=A1draig=20Brady?= <address@hidden>
Date: Mon, 5 Jan 2009 19:13:24 +0000
Subject: [PATCH] build: enable and avoid -Wsign-compare warnings
* configure.ac: allow --enable-gcc-warnings to include -Wsign-compare,
which is included as part of -Wextra.
* src/system.h: Assume st_size, st_blksize, st_blocks of stat struct
are always to be interpreted as positive values, so cast to uintmax_t
in the corresponding extraction macros. A new macro ST_SIZE was
added to do this cast for the st_size member.
* src/copy.c: Use ST_SIZE macro to get an unsigned value.
Use already assigned unsigned variable n, rather than signed n_read
in unsigned comparison.
* src/dd.c: Split out ternary conditional to avoid warning about
the use of signed and unsigned in the expression.
Copy lseek return to a uintmax_t as it's compared against unsigned.
* src/du.c: Store st_size in uintmax_t explicitly to avoid warning.
Also add an assert, to check for the improbable overflow condition.
* src/group-list.c: Use int rather than size_t as variable is used
in signed comparisons.
* src/id.c: Likewise.
* src/ls.c: Use unsigned variables for always positive widths.
Refactor common code to a new format_number_width() function.
Remove unsigned_file_size() and use new ST_SIZE macro instead.
* src/od.c: Use unsigned widths as always positive.
Use ST_SIZE macro to remove an existing cast.
* src/pathchk.c: Compare pathconf limits to signed MAX constants,
as pathconf returns signed values.
* src/pr.c: Use unsigned variables in unsigned comparisons.
* src/shuf.c: Likewise.
* src/ptx.c: Removing existing (redundant) casts of st_size,
and use ST_SIZE on all references to st_size.
* src/shred.c: Use already assigned signed variable sizeof_r,
rather than the unsigned sizeof(r). Don't use signed integer
overflow check that contemporary compilers may remove.
* src/sort.c: Use unsigned file_size in unsigned comparisions.
* src/tac.c: Store lseek return in uintmax_t as it's used in
various unsigned comparisions. Cast it to off_t only in error check.
Remove redundant (off_t) casts.
---
configure.ac | 1 -
src/copy.c | 16 +++++-----
src/dd.c | 13 +++++--
src/du.c | 13 +++++--
src/group-list.c | 4 +-
src/id.c | 4 +-
src/ls.c | 89 +++++++++++++++++++++++++----------------------------
src/od.c | 12 ++++----
src/pathchk.c | 6 ++--
src/pr.c | 8 ++--
src/ptx.c | 10 +++---
src/shred.c | 6 ++--
src/shuf.c | 4 +-
src/sort.c | 6 ++--
src/stat.c | 4 +-
src/system.h | 18 ++++++-----
src/tac.c | 10 +++---
17 files changed, 115 insertions(+), 109 deletions(-)
diff --git a/configure.ac b/configure.ac
index 6163db7..a13e4b5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -61,7 +61,6 @@ if test "$gl_gcc_warnings" = yes; then
gl_WARN_ADD([-Wall])
gl_WARN_ADD([-Wextra])
gl_WARN_ADD([-Wshadow])
- gl_WARN_ADD([-Wno-sign-compare])
gl_WARN_ADD([-Wformat])
gl_WARN_ADD([-Wformat-security])
gl_WARN_ADD([-Wcast-align])
diff --git a/src/copy.c b/src/copy.c
index c9c79a1..96e1865 100644
--- a/src/copy.c
+++ b/src/copy.c
@@ -1,5 +1,5 @@
/* copy.c -- core functions for copying files and directories
- Copyright (C) 89, 90, 91, 1995-2008 Free Software Foundation, Inc.
+ Copyright (C) 89, 90, 91, 1995-2009 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -501,7 +501,7 @@ copy_reg (char const *src_name, char const *dst_name,
needed for a file of its size, then at least one of the blocks in
the file is a hole. */
if (x->sparse_mode == SPARSE_AUTO && S_ISREG (src_open_sb.st_mode)
- && ST_NBLOCKS (src_open_sb) < src_open_sb.st_size / ST_NBLOCKSIZE)
+ && ST_NBLOCKS (src_open_sb) < ST_SIZE (src_open_sb) / ST_NBLOCKSIZE)
make_holes = true;
#endif
}
@@ -527,8 +527,8 @@ copy_reg (char const *src_name, char const *dst_name,
/* Do not bother with a buffer larger than the input file, plus one
byte to make sure the file has not grown while reading it. */
- if (S_ISREG (src_open_sb.st_mode) && src_open_sb.st_size < buf_size)
- buf_size = src_open_sb.st_size + 1;
+ if (S_ISREG (src_open_sb.st_mode) && ST_SIZE (src_open_sb) < buf_size)
+ buf_size = ST_SIZE (src_open_sb) + 1;
/* However, stick with a block size that is a positive multiple of
blcm, overriding the above adjustments. Watch out for
@@ -620,7 +620,7 @@ copy_reg (char const *src_name, char const *dst_name,
last_write_made_hole = false;
/* A short read on a regular file means EOF. */
- if (n_read != buf_size && S_ISREG (src_open_sb.st_mode))
+ if (n != buf_size && S_ISREG (src_open_sb.st_mode))
break;
}
}
@@ -1858,7 +1858,7 @@ copy_internal (char const *src_name, char const *dst_name,
}
else if (S_ISLNK (src_mode))
{
- char *src_link_val = areadlink_with_size (src_name, src_sb.st_size);
+ char *src_link_val = areadlink_with_size (src_name, ST_SIZE (src_sb));
if (src_link_val == NULL)
{
error (0, errno, _("cannot read symbolic link %s"), quote (src_name));
@@ -1872,14 +1872,14 @@ copy_internal (char const *src_name, char const
*dst_name,
int saved_errno = errno;
bool same_link = false;
if (x->update && !new_dst && S_ISLNK (dst_sb.st_mode)
- && dst_sb.st_size == strlen (src_link_val))
+ && ST_SIZE (dst_sb) == strlen (src_link_val))
{
/* See if the destination is already the desired symlink.
FIXME: This behavior isn't documented, and seems wrong
in some cases, e.g., if the destination symlink has the
wrong ownership, permissions, or time stamps. */
char *dest_link_val =
- areadlink_with_size (dst_name, dst_sb.st_size);
+ areadlink_with_size (dst_name, ST_SIZE (dst_sb));
if (dest_link_val && STREQ (dest_link_val, src_link_val))
same_link = true;
free (dest_link_val);
diff --git a/src/dd.c b/src/dd.c
index d683c5d..916a088 100644
--- a/src/dd.c
+++ b/src/dd.c
@@ -1,5 +1,5 @@
/* dd -- convert a file while copying it.
- Copyright (C) 85, 90, 91, 1995-2008 Free Software Foundation, Inc.
+ Copyright (C) 85, 90, 91, 1995-2009 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -910,7 +910,11 @@ parse_symbols (char const *str, struct symbol_value const
*table,
{
if (! entry->symbol[0])
{
- size_t slen = strcomma ? strcomma - str : strlen (str);
+ size_t slen;
+ if (strcomma)
+ slen = strcomma - str;
+ else
+ slen = strlen (str);
error (0, 0, "%s: %s", _(error_msgid),
quotearg_n_style_mem (0, locale_quoting_style, str, slen));
usage (EXIT_FAILURE);
@@ -1326,9 +1330,10 @@ advance_input_after_read_error (size_t nbytes)
if (0 <= offset)
{
off_t diff;
- if (offset == input_offset)
+ uintmax_t p_offset = offset;
+ if (p_offset == input_offset)
return true;
- diff = input_offset - offset;
+ diff = input_offset - p_offset;
if (! (0 <= diff && diff <= nbytes))
error (0, 0, _("warning: invalid file offset after failed read"));
if (0 <= skip_via_lseek (input_file, STDIN_FILENO, diff, SEEK_CUR))
diff --git a/src/du.c b/src/du.c
index 860e8fe..fb17d85 100644
--- a/src/du.c
+++ b/src/du.c
@@ -1,5 +1,5 @@
/* du -- summarize disk usage
- Copyright (C) 1988-1991, 1995-2008 Free Software Foundation, Inc.
+ Copyright (C) 1988-1991, 1995-2009 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -524,10 +524,15 @@ process_file (FTS *fts, FTSENT *ent)
}
else
{
+ uintmax_t size = ST_SIZE (*sb);
+ if (!apparent_size)
+ {
+ uintmax_t blocks = ST_NBLOCKS (*sb);
+ assert (blocks <= UINTMAX_MAX/ST_NBLOCKSIZE);
+ size = blocks * ST_NBLOCKSIZE;
+ }
duinfo_set (&dui,
- (apparent_size
- ? sb->st_size
- : (uintmax_t) ST_NBLOCKS (*sb) * ST_NBLOCKSIZE),
+ size,
(time_type == time_mtime ? get_stat_mtime (sb)
: time_type == time_atime ? get_stat_atime (sb)
: get_stat_ctime (sb)));
diff --git a/src/group-list.c b/src/group-list.c
index 3547ed6..46895b4 100644
--- a/src/group-list.c
+++ b/src/group-list.c
@@ -1,5 +1,5 @@
/* group-list.c --Print a list of group IDs or names.
- Copyright (C) 1989-2008 Free Software Foundation, Inc.
+ Copyright (C) 1989-2009 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -57,7 +57,7 @@ print_group_list (const char *username,
#if HAVE_GETGROUPS
{
GETGROUPS_T *groups;
- size_t i;
+ int i;
int n_groups = mgetgroups (username, (pwd ? pwd->pw_gid : (gid_t) -1),
&groups);
diff --git a/src/id.c b/src/id.c
index 156b066..05ad2d8 100644
--- a/src/id.c
+++ b/src/id.c
@@ -1,5 +1,5 @@
/* id -- print real and effective UIDs and GIDs
- Copyright (C) 1989-2008 Free Software Foundation, Inc.
+ Copyright (C) 1989-2009 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -294,7 +294,7 @@ print_full_info (const char *username)
#if HAVE_GETGROUPS
{
GETGROUPS_T *groups;
- size_t i;
+ int i;
int n_groups = mgetgroups (username, (pwd ? pwd->pw_gid : (gid_t) -1),
&groups);
diff --git a/src/ls.c b/src/ls.c
index b03aebc..f2ba711 100644
--- a/src/ls.c
+++ b/src/ls.c
@@ -1,5 +1,5 @@
/* `dir', `vdir' and `ls' directory listing programs for GNU.
- Copyright (C) 85, 88, 90, 91, 1995-2008 Free Software Foundation, Inc.
+ Copyright (C) 85, 88, 90, 91, 1995-2009 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -233,8 +233,11 @@ static void print_dir (char const *name, char const
*realname,
bool command_line_arg);
static void print_file_name_and_frills (const struct fileinfo *f);
static void print_horizontal (void);
-static int format_user_width (uid_t u);
-static int format_group_width (gid_t g);
+static unsigned int format_user_width (uid_t u);
+static unsigned int format_group_width (gid_t g);
+static unsigned int format_number_width (uintmax_t number,
+ uintmax_t from_blksize,
+ uintmax_t to_blksize);
static void print_long_format (const struct fileinfo *f);
static void print_many_per_line (void);
static void print_name_with_quoting (const char *p, mode_t mode,
@@ -331,16 +334,16 @@ static bool any_has_acl;
block sizes, link counts, owners, groups, authors, major device
numbers, minor device numbers, and file sizes, respectively. */
-static int inode_number_width;
-static int block_size_width;
-static int nlink_width;
-static int scontext_width;
-static int owner_width;
-static int group_width;
-static int author_width;
-static int major_device_number_width;
-static int minor_device_number_width;
-static int file_size_width;
+static unsigned int inode_number_width;
+static unsigned int block_size_width;
+static unsigned int nlink_width;
+static unsigned int scontext_width;
+static unsigned int owner_width;
+static unsigned int group_width;
+static unsigned int author_width;
+static unsigned int major_device_number_width;
+static unsigned int minor_device_number_width;
+static unsigned int file_size_width;
/* Option flags */
@@ -2528,16 +2531,6 @@ file_ignored (char const *name)
|| patterns_match (ignore_patterns, name));
}
-/* POSIX requires that a file size be printed without a sign, even
- when negative. Assume the typical case where negative sizes are
- actually positive values that have wrapped around. */
-
-static uintmax_t
-unsigned_file_size (off_t size)
-{
- return size + (size < 0) * ((uintmax_t) OFF_T_MAX - OFF_T_MIN + 1);
-}
-
/* Enter and remove entries in the table `cwd_file'. */
/* Empty the table of files. */
@@ -2798,10 +2791,8 @@ gobble_file (char const *name, enum filetype type, ino_t
inode,
blocks = ST_NBLOCKS (f->stat);
if (format == long_format || print_block_size)
{
- char buf[LONGEST_HUMAN_READABLE + 1];
- int len = mbswidth (human_readable (blocks, buf, human_output_opts,
- ST_NBLOCKSIZE, output_block_size),
- 0);
+ unsigned int len;
+ len = format_number_width (blocks, ST_NBLOCKSIZE, output_block_size);
if (block_size_width < len)
block_size_width = len;
}
@@ -2810,21 +2801,21 @@ gobble_file (char const *name, enum filetype type,
ino_t inode,
{
if (print_owner)
{
- int len = format_user_width (f->stat.st_uid);
+ unsigned int len = format_user_width (f->stat.st_uid);
if (owner_width < len)
owner_width = len;
}
if (print_group)
{
- int len = format_group_width (f->stat.st_gid);
+ unsigned int len = format_group_width (f->stat.st_gid);
if (group_width < len)
group_width = len;
}
if (print_author)
{
- int len = format_user_width (f->stat.st_author);
+ unsigned int len = format_user_width (f->stat.st_author);
if (author_width < len)
author_width = len;
}
@@ -2832,7 +2823,7 @@ gobble_file (char const *name, enum filetype type, ino_t
inode,
if (print_scontext)
{
- int len = strlen (f->scontext);
+ size_t len = strlen (f->scontext);
if (scontext_width < len)
scontext_width = len;
}
@@ -2840,14 +2831,15 @@ gobble_file (char const *name, enum filetype type,
ino_t inode,
if (format == long_format)
{
char b[INT_BUFSIZE_BOUND (uintmax_t)];
- int b_len = strlen (umaxtostr (f->stat.st_nlink, b));
+ size_t b_len = strlen (umaxtostr (f->stat.st_nlink, b));
if (nlink_width < b_len)
nlink_width = b_len;
if (S_ISCHR (f->stat.st_mode) || S_ISBLK (f->stat.st_mode))
{
char buf[INT_BUFSIZE_BOUND (uintmax_t)];
- int len = strlen (umaxtostr (major (f->stat.st_rdev), buf));
+ unsigned int len;
+ len = strlen (umaxtostr (major (f->stat.st_rdev), buf));
if (major_device_number_width < len)
major_device_number_width = len;
len = strlen (umaxtostr (minor (f->stat.st_rdev), buf));
@@ -2859,11 +2851,9 @@ gobble_file (char const *name, enum filetype type, ino_t
inode,
}
else
{
- char buf[LONGEST_HUMAN_READABLE + 1];
- uintmax_t size = unsigned_file_size (f->stat.st_size);
- int len = mbswidth (human_readable (size, buf, human_output_opts,
- 1, file_output_block_size),
- 0);
+ uintmax_t size = ST_SIZE (f->stat);
+ unsigned int len;
+ len = format_number_width (size, 1, file_output_block_size);
if (file_size_width < len)
file_size_width = len;
}
@@ -2873,7 +2863,7 @@ gobble_file (char const *name, enum filetype type, ino_t
inode,
if (print_inode)
{
char buf[INT_BUFSIZE_BOUND (uintmax_t)];
- int len = strlen (umaxtostr (f->stat.st_ino, buf));
+ size_t len = strlen (umaxtostr (f->stat.st_ino, buf));
if (inode_number_width < len)
inode_number_width = len;
}
@@ -3396,14 +3386,11 @@ format_group (gid_t g, int width, bool stat_ok)
/* Return the number of columns that format_user_or_group will print. */
-static int
+static unsigned int
format_user_or_group_width (char const *name, unsigned long int id)
{
if (name)
- {
- int len = mbswidth (name, 0);
- return MAX (0, len);
- }
+ return mbswidth (name, 0); /* >=0 when flags=0. */
else
{
char buf[INT_BUFSIZE_BOUND (unsigned long int)];
@@ -3414,7 +3401,7 @@ format_user_or_group_width (char const *name, unsigned
long int id)
/* Return the number of columns that format_user will print. */
-static int
+static unsigned int
format_user_width (uid_t u)
{
return format_user_or_group_width (numeric_ids ? NULL : getuser (u), u);
@@ -3422,12 +3409,20 @@ format_user_width (uid_t u)
/* Likewise, for groups. */
-static int
+static unsigned int
format_group_width (gid_t g)
{
return format_user_or_group_width (numeric_ids ? NULL : getgroup (g), g);
}
+static unsigned int
+format_number_width (uintmax_t number, uintmax_t from_blksize, uintmax_t
to_blksize)
+{
+ char buf[LONGEST_HUMAN_READABLE + 1];
+ return mbswidth (human_readable (number, buf, human_output_opts,
+ from_blksize, to_blksize),
+ 0); /* flags=0 => len>=0. */
+}
/* Print information about F in long format. */
@@ -3565,7 +3560,7 @@ print_long_format (const struct fileinfo *f)
char const *size =
(! f->stat_ok
? "?"
- : human_readable (unsigned_file_size (f->stat.st_size),
+ : human_readable (ST_SIZE (f->stat),
hbuf, human_output_opts, 1, file_output_block_size));
int pad;
for (pad = file_size_width - mbswidth (size, 0); 0 < pad; pad--)
diff --git a/src/od.c b/src/od.c
index 2dcb398..90b7353 100644
--- a/src/od.c
+++ b/src/od.c
@@ -1,5 +1,5 @@
/* od -- dump files in octal and other formats
- Copyright (C) 92, 1995-2008 Free Software Foundation, Inc.
+ Copyright (C) 92, 1995-2009 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -119,7 +119,7 @@ struct tspec
char const *fmt, int width, int pad);
char fmt_string[FMT_BYTES_ALLOCATED]; /* Of the style "%*d". */
bool hexl_mode_trailer;
- int field_width; /* Minimum width of a field, excluding leading space. */
+ unsigned int field_width; /* Minimum width, excluding leading space. */
int pad_width; /* Total padding to be divided among fields. */
};
@@ -991,10 +991,10 @@ skip (uintmax_t n_skip)
and go on to the next file. Skip this optimization also
when st_size is 0, because some kernels report that
nonempty files in /proc have st_size == 0. */
- if (S_ISREG (file_stats.st_mode) && 0 < file_stats.st_size)
+ if (S_ISREG (file_stats.st_mode) && ST_SIZE (file_stats))
{
- if ((uintmax_t) file_stats.st_size < n_skip)
- n_skip -= file_stats.st_size;
+ if (ST_SIZE (file_stats) < n_skip)
+ n_skip -= ST_SIZE (file_stats);
else
{
if (fseeko (in_stream, n_skip, SEEK_CUR) != 0)
@@ -1883,7 +1883,7 @@ it must be one character from [doxn]"),
for (i = 0; i < n_specs; i++)
{
int fields_per_block = bytes_per_block / width_bytes[spec[i].size];
- int block_width = (spec[i].field_width + 1) * fields_per_block;
+ unsigned int block_width = (spec[i].field_width + 1) * fields_per_block;
if (width_per_block < block_width)
width_per_block = block_width;
}
diff --git a/src/pathchk.c b/src/pathchk.c
index 5dbc7da..5261345 100644
--- a/src/pathchk.c
+++ b/src/pathchk.c
@@ -1,5 +1,5 @@
/* pathchk -- check whether file names are valid or portable
- Copyright (C) 1991-2008 Free Software Foundation, Inc.
+ Copyright (C) 1991-2009 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -323,7 +323,7 @@ validate_file_name (char *file, bool
check_basic_portability,
dir);
return false;
}
- maxsize = MIN (size, SIZE_MAX);
+ maxsize = MIN (size, SSIZE_MAX);
}
if (maxsize <= filelen)
@@ -385,7 +385,7 @@ validate_file_name (char *file, bool
check_basic_portability,
len = pathconf (dir, _PC_NAME_MAX);
*start = c;
if (0 <= len)
- name_max = MIN (len, SIZE_MAX);
+ name_max = MIN (len, SSIZE_MAX);
else
switch (errno)
{
diff --git a/src/pr.c b/src/pr.c
index d2b6714..308a025 100644
--- a/src/pr.c
+++ b/src/pr.c
@@ -1,5 +1,5 @@
/* pr -- convert text files for printing.
- Copyright (C) 88, 91, 1995-2008 Free Software Foundation, Inc.
+ Copyright (C) 88, 91, 1995-2009 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -455,7 +455,7 @@ static char *buff;
/* Index of the position in buff where the next character
will be stored. */
-static int buff_current;
+static unsigned int buff_current;
/* The number of characters in buff.
Used for allocation of buff and to detect overflow of buff. */
@@ -1944,8 +1944,8 @@ static void
store_columns (void)
{
int i, j;
- int line = 0;
- int buff_start;
+ unsigned int line = 0;
+ unsigned int buff_start;
int last_col; /* The rightmost column which will be saved in
buff */
COLUMN *p;
diff --git a/src/ptx.c b/src/ptx.c
index c04c90c..8818c03 100644
--- a/src/ptx.c
+++ b/src/ptx.c
@@ -1,5 +1,5 @@
/* Permuted index for GNU, with keywords in their context.
- Copyright (C) 1990, 1991, 1993, 1998-2008 Free Software Foundation, Inc.
+ Copyright (C) 1990, 1991, 1993, 1998-2009 Free Software Foundation, Inc.
François Pinard <address@hidden>, 1988.
This program is free software: you can redistribute it and/or modify
@@ -541,11 +541,11 @@ swallow_file_in_memory (const char *file_name, BLOCK
*block)
{
size_t in_memory_size;
- block->start = xmalloc ((size_t) stat_block.st_size);
+ block->start = xmalloc (ST_SIZE (stat_block));
if ((in_memory_size = read (file_handle,
- block->start, (size_t) stat_block.st_size))
- != stat_block.st_size)
+ block->start, ST_SIZE (stat_block)))
+ != ST_SIZE (stat_block))
{
#if MSDOS
/* On MSDOS, in memory size may be smaller than the file
@@ -554,7 +554,7 @@ swallow_file_in_memory (const char *file_name, BLOCK *block)
minimum is when all lines are empty and terminated by
CR+LF. */
if (in_memory_size != (size_t)-1
- && in_memory_size >= stat_block.st_size / 2)
+ && in_memory_size >= ST_SIZE (stat_block) / 2)
block->start = xrealloc (block->start, in_memory_size);
else
#endif /* not MSDOS */
diff --git a/src/shred.c b/src/shred.c
index 1e7bffb..224f671 100644
--- a/src/shred.c
+++ b/src/shred.c
@@ -1,6 +1,6 @@
/* shred.c - overwrite files and devices to make it harder to recover data
- Copyright (C) 1999-2008 Free Software Foundation, Inc.
+ Copyright (C) 1999-2009 Free Software Foundation, Inc.
Copyright (C) 1997, 1998, 1999 Colin Plumb.
This program is free software: you can redistribute it and/or modify
@@ -399,7 +399,7 @@ dopass (int fd, char const *qname, off_t *sizep, int type,
/* Constant fill patterns need only be set up once. */
if (type >= 0)
{
- lim = (0 <= size && size < sizeof_r ? size : sizeof r);
+ lim = (0 <= size && size < sizeof_r ? size : sizeof_r);
fillpattern (type, r.u, lim);
passname (r.u, pass_string);
}
@@ -488,7 +488,7 @@ dopass (int fd, char const *qname, off_t *sizep, int type,
/* Okay, we have written "soff" bytes. */
- if (offset + soff < offset)
+ if (offset > OFF_T_MAX - (off_t) soff)
{
error (0, 0, _("%s: file too large"), qname);
return -1;
diff --git a/src/shuf.c b/src/shuf.c
index 977eedc..180ff21 100644
--- a/src/shuf.c
+++ b/src/shuf.c
@@ -1,6 +1,6 @@
/* Shuffle lines of text.
- Copyright (C) 2006, 2007-2008 Free Software Foundation, Inc.
+ Copyright (C) 2006, 2007-2009 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -164,7 +164,7 @@ read_input (FILE *in, char eolbyte, char ***pline)
off_t current_offset = ftello (in);
if (0 <= current_offset)
{
- off_t remaining_size =
+ uintmax_t remaining_size =
(current_offset < file_size ? file_size - current_offset : 0);
if (SIZE_MAX - 2 < remaining_size)
xalloc_die ();
diff --git a/src/sort.c b/src/sort.c
index f438563..df466e9 100644
--- a/src/sort.c
+++ b/src/sort.c
@@ -1,5 +1,5 @@
/* sort - sort lines of text (with all kinds of options).
- Copyright (C) 1988, 1991-2008 Free Software Foundation, Inc.
+ Copyright (C) 1988, 1991-2009 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -1281,7 +1281,7 @@ sort_buffer_size (FILE *const *fps, size_t nfps,
for (i = 0; i < nfiles; i++)
{
struct stat st;
- off_t file_size;
+ uintmax_t file_size;
size_t worst_case;
if ((i < nfps ? fstat (fileno (fps[i]), &st)
@@ -1291,7 +1291,7 @@ sort_buffer_size (FILE *const *fps, size_t nfps,
die (_("stat failed"), files[i]);
if (S_ISREG (st.st_mode))
- file_size = st.st_size;
+ file_size = ST_SIZE (st);
else
{
/* The file has unknown size. If the user specified a sort
diff --git a/src/stat.c b/src/stat.c
index feea4b7..e084b18 100644
--- a/src/stat.c
+++ b/src/stat.c
@@ -573,7 +573,7 @@ print_stat (char *pformat, size_t prefix_len, char m,
out_string (pformat, prefix_len, quote (filename));
if (S_ISLNK (statbuf->st_mode))
{
- char *linkname = areadlink_with_size (filename, statbuf->st_size);
+ char *linkname = areadlink_with_size (filename, ST_SIZE (*statbuf));
if (linkname == NULL)
{
error (0, errno, _("cannot read symbolic link %s"),
@@ -633,7 +633,7 @@ print_stat (char *pformat, size_t prefix_len, char m,
out_uint_x (pformat, prefix_len, minor (statbuf->st_rdev));
break;
case 's':
- out_uint (pformat, prefix_len, statbuf->st_size);
+ out_uint (pformat, prefix_len, ST_SIZE (*statbuf));
break;
case 'B':
out_uint (pformat, prefix_len, ST_NBLOCKSIZE);
diff --git a/src/system.h b/src/system.h
index 020f83b..0d97082 100644
--- a/src/system.h
+++ b/src/system.h
@@ -1,5 +1,5 @@
/* system-dependent definitions for coreutils
- Copyright (C) 1989, 1991-2008 Free Software Foundation, Inc.
+ Copyright (C) 1989, 1991-2009 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -172,20 +172,22 @@ enum
# define DEV_BSIZE 4096
#endif
-/* Extract or fake data from a `struct stat'.
+/* Extract or fake unsigned data from a `struct stat'.
+ ST_SIZE: Number of bytes in the file, assumed >= 0.
ST_BLKSIZE: Preferred I/O blocksize for the file, in bytes.
ST_NBLOCKS: Number of blocks in the file, including indirect blocks.
ST_NBLOCKSIZE: Size of blocks used when calculating ST_NBLOCKS. */
+#define ST_SIZE(statbuf) ((uintmax_t) (statbuf).st_size)
#ifndef HAVE_STRUCT_STAT_ST_BLOCKS
# define ST_BLKSIZE(statbuf) DEV_BSIZE
# if defined _POSIX_SOURCE || !defined BSIZE /* fileblocks.c uses BSIZE. */
# define ST_NBLOCKS(statbuf) \
- ((statbuf).st_size / ST_NBLOCKSIZE + ((statbuf).st_size % ST_NBLOCKSIZE !=
0))
+ (ST_SIZE(statbuf) / ST_NBLOCKSIZE + (ST_SIZE(statbuf) % ST_NBLOCKSIZE != 0))
# else /* !_POSIX_SOURCE && BSIZE */
# define ST_NBLOCKS(statbuf) \
(S_ISREG ((statbuf).st_mode) \
|| S_ISDIR ((statbuf).st_mode) \
- ? st_blocks ((statbuf).st_size) : 0)
+ ? (uintmax_t) st_blocks (ST_SIZE(statbuf)) : 0)
# endif /* !_POSIX_SOURCE && BSIZE */
#else /* HAVE_STRUCT_STAT_ST_BLOCKS */
/* Some systems, like Sequents, return st_blksize of 0 on pipes.
@@ -197,9 +199,9 @@ enum
suffice, since "cat" sometimes multiplies the result by 4.) If
anyone knows of a system for which this limit is too small, please
report it as a bug in this code. */
-# define ST_BLKSIZE(statbuf) ((0 < (statbuf).st_blksize \
- && (statbuf).st_blksize <= SIZE_MAX / 8 + 1) \
- ? (statbuf).st_blksize : DEV_BSIZE)
+# define ST_BLKSIZE(statbuf) (((statbuf).st_blksize && (uintmax_t) \
+ (statbuf).st_blksize <= SIZE_MAX / 8 + 1) \
+ ? (uintmax_t) (statbuf).st_blksize : DEV_BSIZE)
# if defined hpux || defined __hpux__ || defined __hpux
/* HP-UX counts st_blocks in 1024-byte units.
This loses when mixing HP-UX and BSD file systems with NFS. */
@@ -220,7 +222,7 @@ enum
#endif /* HAVE_STRUCT_STAT_ST_BLOCKS */
#ifndef ST_NBLOCKS
-# define ST_NBLOCKS(statbuf) ((statbuf).st_blocks)
+# define ST_NBLOCKS(statbuf) ((uintmax_t) (statbuf).st_blocks)
#endif
#ifndef ST_NBLOCKSIZE
diff --git a/src/tac.c b/src/tac.c
index be8f3ab..7b19c16 100644
--- a/src/tac.c
+++ b/src/tac.c
@@ -1,5 +1,5 @@
/* tac - concatenate and print files in reverse
- Copyright (C) 1988-1991, 1995-2006, 2008 Free Software Foundation, Inc.
+ Copyright (C) 1988-1991, 1995-2006, 2009 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -205,7 +205,7 @@ tac_seekable (int input_fd, const char *file)
size_t saved_record_size;
/* Offset in the file of the next read. */
- off_t file_pos;
+ uintmax_t file_pos;
/* True if `output' has not been called yet for any file.
Only used when the separator is attached to the preceding record. */
@@ -215,8 +215,8 @@ tac_seekable (int input_fd, const char *file)
size_t match_length1 = match_length - 1; /* Speed optimization, non-regexp.
*/
/* Find the size of the input file. */
- file_pos = lseek (input_fd, (off_t) 0, SEEK_END);
- if (file_pos < 1)
+ file_pos = lseek (input_fd, 0, SEEK_END);
+ if ((off_t) file_pos < 1)
return true; /* It's an empty file. */
/* Arrange for the first read to lop off enough to leave the rest of the
@@ -546,7 +546,7 @@ tac_file (const char *filename)
}
}
- file_size = lseek (fd, (off_t) 0, SEEK_END);
+ file_size = lseek (fd, 0, SEEK_END);
ok = (file_size < 0 || isatty (fd)
? tac_nonseekable (fd, filename)
--
1.5.3.6
- Re: stat signed/unsigned, Michael Meskes, 2009/01/02
- Re: stat signed/unsigned, Jim Meyering, 2009/01/02
- Re: stat signed/unsigned, Michael Meskes, 2009/01/02
- Re: stat signed/unsigned, Pádraig Brady, 2009/01/06
- Re: stat signed/unsigned, Jim Meyering, 2009/01/06
- Re: stat signed/unsigned, Pádraig Brady, 2009/01/06
- Re: stat signed/unsigned, Jim Meyering, 2009/01/06
- Re: stat signed/unsigned,
Pádraig Brady <=
- Re: stat signed/unsigned, Paul Eggert, 2009/01/08
- Re: stat signed/unsigned, Pádraig Brady, 2009/01/09
- Re: stat signed/unsigned, Pádraig Brady, 2009/01/15
- Re: stat signed/unsigned, Jim Meyering, 2009/01/16
- Re: stat signed/unsigned, Pádraig Brady, 2009/01/16