partx: fix --nr usage

Reported-by: Serge van den Boom <serge+util-linux@vdboom.org>
Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
Karel Zak 2016-03-22 15:49:00 +01:00
parent 6988998b66
commit 2d47fa3921
4 changed files with 48 additions and 17 deletions

View File

@ -41,7 +41,7 @@ The library libsmartcols has been massively improved to print table ranges,
multi-line cells, table titles and to support continuous printing.
The package build system and code have been improved to be more portable to
non-Linux systems (BSD, XOs).
non-Linux systems (BSD, OSX).
The package does not provide fallback solutions for openat-family functions
anymore.

View File

@ -68,7 +68,7 @@ Do not use it in newly written scripts.
Specify the range of partitions. For backward compatibility also the
format \fIM\fB\-\fIN\fR is supported.
The range may contain negative numbers, for example
.B \-\-nr :\-1
.B \-\-nr -\1:\-1
means the last partition, and
.B \-\-nr \-2:\-1
means the last two partitions. Supported range specifications are:

View File

@ -267,6 +267,30 @@ dflt:
return SLICES_MAX;
}
static int recount_range_by_pt(blkid_partlist ls, int *lower, int *upper)
{
int n = 0, i, nparts = blkid_partlist_numof_partitions(ls);
for (i = 0; i < nparts; i++) {
blkid_partition par = blkid_partlist_get_partition(ls, i);
int partno = blkid_partition_get_partno(par);
n = max(partno, n);
}
if (*lower < 0)
*lower = n + *lower + 1;
if (*upper < 0)
*upper = n + *upper + 1;
if (*lower > *upper && *upper != 0) {
warnx(_("specified range <%d:%d> does not make sense"), *lower, *upper);
return -EINVAL;
}
if (verbose)
printf(_("range recount: max partno=%d, lower=%d, upper=%d\n"), n, *lower, *upper);
return 0;
}
static void del_parts_warnx(const char *device, int first, int last)
{
if (first == last)
@ -284,6 +308,7 @@ static int del_parts(int fd, const char *device, dev_t devno,
assert(fd >= 0);
assert(device);
/* recount range by information in /sys */
if (!lower)
lower = 1;
if (!upper || lower < 0 || upper < 0) {
@ -343,12 +368,16 @@ static void add_parts_warnx(const char *device, int first, int last)
static int add_parts(int fd, const char *device,
blkid_partlist ls, int lower, int upper)
{
int i, nparts, rc = 0, errfirst = 0, errlast = 0;
int i, nparts, rc, errfirst = 0, errlast = 0;
assert(fd >= 0);
assert(device);
assert(ls);
rc = recount_range_by_pt(ls, &lower, &upper);
if (rc)
return rc;
nparts = blkid_partlist_numof_partitions(ls);
for (i = 0; i < nparts; i++) {
@ -430,6 +459,8 @@ static int upd_parts(int fd, const char *device, dev_t devno,
assert(device);
assert(ls);
/* recount range by information in /sys, if on disk number of
* partitions is greater than in /sys the use on-disk limit */
nparts = blkid_partlist_numof_partitions(ls);
if (!lower)
lower = 1;
@ -505,10 +536,14 @@ static int upd_parts(int fd, const char *device, dev_t devno,
static int list_parts(blkid_partlist ls, int lower, int upper)
{
int i, nparts;
int i, nparts, rc;
assert(ls);
rc = recount_range_by_pt(ls, &lower, &upper);
if (rc)
return rc;
nparts = blkid_partlist_numof_partitions(ls);
for (i = 0; i < nparts; i++) {
@ -645,6 +680,10 @@ static int show_parts(blkid_partlist ls, int scols_flags, int lower, int upper)
}
}
rc = recount_range_by_pt(ls, &lower, &upper);
if (rc)
goto done;
for (i = 0; i < nparts; i++) {
blkid_partition par = blkid_partlist_get_partition(ls, i);
int n = blkid_partition_get_partno(par);
@ -880,6 +919,9 @@ int main(int argc, char **argv)
} else {
device = argv[optind];
wholedisk = xstrdup(argv[optind + 1]);
if (device && wholedisk && !startswith(device, wholedisk))
errx(EXIT_FAILURE, _("partition and disk name do not match"));
}
} else if (optind == argc - 1) {
/* passed only one arg (ie: /dev/sda3 or /dev/sda) */
@ -964,18 +1006,6 @@ int main(int argc, char **argv)
ls = get_partlist(pr, wholedisk, type);
if (ls) {
int n = blkid_partlist_numof_partitions(ls);
if (lower < 0)
lower = n + lower + 1;
if (upper < 0)
upper = n + upper + 1;
if (lower > upper) {
warnx(_("specified range <%d:%d> "
"does not make sense"), lower, upper);
rc = -1, what = ACT_NONE;
}
switch (what) {
case ACT_SHOW:
rc = show_parts(ls, scols_flags, lower, upper);
@ -988,6 +1018,7 @@ int main(int argc, char **argv)
break;
case ACT_UPD:
rc = upd_parts(fd, wholedisk, disk_devno, ls, lower, upper);
break;
case ACT_NONE:
break;
default:

View File

@ -734,7 +734,7 @@ int parse_range(const char *str, int *lower, int *upper, int def)
return -1;
if (*end == ':' && !*(end + 1)) /* <M:> */
*upper = 0;
*upper = def;
else if (*end == '-' || *end == ':') { /* <M:N> <M-N> */
str = end + 1;
end = NULL;