[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Bug in find's -size (+patch)
From: |
James Youngman |
Subject: |
Re: Bug in find's -size (+patch) |
Date: |
Mon, 7 Feb 2005 08:11:50 +0000 |
User-agent: |
Mutt/1.3.28i |
On Sun, Feb 06, 2005 at 11:47:49PM -0500, Amir Sela wrote:
> > > It's simply broken. There's no other way to put it.
> >
> > Well, it complies with both the POSIX standard and historic usage of
> > "find". I might concede that under some circumstances the current
> > behaviour is _inconvenient_, but I find it hard to agree that it is
> > _broken_.
>
> So, searching for 'file . -size -2G' and finding files which are really
> under 1G and not under 2, is an inconvenience?
So, are you in effect advocating the following change?
Index: find/pred.c
===================================================================
RCS file: /cvsroot/findutils/findutils/find/pred.c,v
retrieving revision 1.54
diff -U8 -r1.54 pred.c
--- find/pred.c 6 Feb 2005 09:23:52 -0000 1.54
+++ find/pred.c 7 Feb 2005 08:10:20 -0000
@@ -1221,33 +1221,54 @@
int len = strlen (pathname);
(void) stat_buf;
if (re_match (pred_ptr->args.regex, pathname, len, 0,
(struct re_registers *) NULL) == len)
return (true);
return (false);
}
+/* Implement -size.
+ *
+ * POSIX:
+ *| The primary shall evaluate as true if the file size in bytes, divided
+ *| by 512 and rounded up to the next integer, is n. If n is followed by
+ *| the character 'c', the size shall be in bytes.
+ *|
+ *| In the descriptions, wherever n is used as a primary argument, it
+ *| shall be interpreted as a decimal integer optionally preceded by a
+ *| plus ( '+' ) or minus ( '-' ) sign, as follows:
+ *|
+ *| +n More than n.
+ *| n Exactly n.
+ *| -n Less than n.
+ *
+ * We allow "-size -2M to match a file which is 1.5Mb, but should a
+ * 2Mb file also match -size -2M. I assume not.
+ */
boolean
pred_size (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
{
uintmax_t f_val;
(void) pathname;
f_val = ((stat_buf->st_size / pred_ptr->args.size.blocksize)
+ (stat_buf->st_size % pred_ptr->args.size.blocksize != 0));
switch (pred_ptr->args.size.kind)
{
case COMP_GT:
if (f_val > pred_ptr->args.size.size)
return (true);
break;
case COMP_LT:
- if (f_val < pred_ptr->args.size.size)
- return (true);
+ if (pred_ptr->args.size.blocksize > 1
+ && (stat_buf->st_size % pred_ptr->args.size.blocksize != 0))
+ return f_val <= pred_ptr->args.size.size; /* allow 1.5Mb file to match
-size -2M */
+ else
+ return f_val < pred_ptr->args.size.size;
break;
case COMP_EQ:
if (f_val == pred_ptr->args.size.size)
return (true);
break;
}
return (false);
}