diff options
author | Ron Yorston <rmy@pobox.com> | 2020-01-08 12:30:49 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2020-01-08 12:30:49 +0000 |
commit | a9271a8e97e6e7be5285330d5f19352decabf807 (patch) | |
tree | bf3c4464c369a15a46454792dac167505f74769f /util-linux | |
parent | b0b7ab792bc1f45963f4b84b94faaf05054e1613 (diff) | |
parent | 9ec836c033fc6e55e80f3309b3e05acdf09bb297 (diff) | |
download | busybox-w32-a9271a8e97e6e7be5285330d5f19352decabf807.tar.gz busybox-w32-a9271a8e97e6e7be5285330d5f19352decabf807.tar.bz2 busybox-w32-a9271a8e97e6e7be5285330d5f19352decabf807.zip |
Merge branch 'busybox' into merge
Diffstat (limited to 'util-linux')
-rw-r--r-- | util-linux/fdisk.c | 33 | ||||
-rw-r--r-- | util-linux/fdisk_aix.c | 40 | ||||
-rw-r--r-- | util-linux/fdisk_gpt.c | 6 | ||||
-rw-r--r-- | util-linux/fdisk_osf.c | 4 | ||||
-rw-r--r-- | util-linux/fdisk_sgi.c | 12 | ||||
-rw-r--r-- | util-linux/fdisk_sun.c | 16 | ||||
-rw-r--r-- | util-linux/rdate.c | 8 | ||||
-rw-r--r-- | util-linux/taskset.c | 140 |
8 files changed, 189 insertions, 70 deletions
diff --git a/util-linux/fdisk.c b/util-linux/fdisk.c index f28d4fdd2..e58cb0fd1 100644 --- a/util-linux/fdisk.c +++ b/util-linux/fdisk.c | |||
@@ -299,9 +299,6 @@ static int get_boot(enum action what); | |||
299 | static int get_boot(void); | 299 | static int get_boot(void); |
300 | #endif | 300 | #endif |
301 | 301 | ||
302 | #define PLURAL 0 | ||
303 | #define SINGULAR 1 | ||
304 | |||
305 | static sector_t get_start_sect(const struct partition *p); | 302 | static sector_t get_start_sect(const struct partition *p); |
306 | static sector_t get_nr_sects(const struct partition *p); | 303 | static sector_t get_nr_sects(const struct partition *p); |
307 | 304 | ||
@@ -591,18 +588,18 @@ partname(const char *dev, int pno, int lth) | |||
591 | return bufp; | 588 | return bufp; |
592 | } | 589 | } |
593 | 590 | ||
591 | #if ENABLE_FEATURE_SGI_LABEL || ENABLE_FEATURE_OSF_LABEL | ||
594 | static ALWAYS_INLINE struct partition * | 592 | static ALWAYS_INLINE struct partition * |
595 | get_part_table(int i) | 593 | get_part_table(int i) |
596 | { | 594 | { |
597 | return ptes[i].part_table; | 595 | return ptes[i].part_table; |
598 | } | 596 | } |
597 | #endif | ||
599 | 598 | ||
600 | static const char * | 599 | static ALWAYS_INLINE const char * |
601 | str_units(int n) | 600 | str_units(void) |
602 | { /* n==1: use singular */ | 601 | { |
603 | if (n == 1) | 602 | return display_in_cyl_units ? "cylinder" : "sector"; |
604 | return display_in_cyl_units ? "cylinder" : "sector"; | ||
605 | return display_in_cyl_units ? "cylinders" : "sectors"; | ||
606 | } | 603 | } |
607 | 604 | ||
608 | static int | 605 | static int |
@@ -1778,8 +1775,8 @@ change_units(void) | |||
1778 | { | 1775 | { |
1779 | display_in_cyl_units = !display_in_cyl_units; | 1776 | display_in_cyl_units = !display_in_cyl_units; |
1780 | update_units(); | 1777 | update_units(); |
1781 | printf("Changing display/entry units to %s\n", | 1778 | printf("Changing display/entry units to %ss\n", |
1782 | str_units(PLURAL)); | 1779 | str_units()); |
1783 | } | 1780 | } |
1784 | 1781 | ||
1785 | static void | 1782 | static void |
@@ -2030,8 +2027,7 @@ check_consistency(const struct partition *p, int partition) | |||
2030 | static void | 2027 | static void |
2031 | list_disk_geometry(void) | 2028 | list_disk_geometry(void) |
2032 | { | 2029 | { |
2033 | ullong bytes = ((ullong)total_number_of_sectors << 9); | 2030 | ullong xbytes = total_number_of_sectors / (1024*1024 / 512); |
2034 | ullong xbytes = bytes / (1024*1024); | ||
2035 | char x = 'M'; | 2031 | char x = 'M'; |
2036 | 2032 | ||
2037 | if (xbytes >= 10000) { | 2033 | if (xbytes >= 10000) { |
@@ -2041,11 +2037,12 @@ list_disk_geometry(void) | |||
2041 | } | 2037 | } |
2042 | printf("Disk %s: %llu %cB, %llu bytes, %"SECT_FMT"u sectors\n" | 2038 | printf("Disk %s: %llu %cB, %llu bytes, %"SECT_FMT"u sectors\n" |
2043 | "%u cylinders, %u heads, %u sectors/track\n" | 2039 | "%u cylinders, %u heads, %u sectors/track\n" |
2044 | "Units: %s of %u * %u = %u bytes\n\n", | 2040 | "Units: %ss of %u * %u = %u bytes\n" |
2041 | "\n", | ||
2045 | disk_device, xbytes, x, | 2042 | disk_device, xbytes, x, |
2046 | bytes, total_number_of_sectors, | 2043 | ((ullong)total_number_of_sectors * 512), total_number_of_sectors, |
2047 | g_cylinders, g_heads, g_sectors, | 2044 | g_cylinders, g_heads, g_sectors, |
2048 | str_units(PLURAL), | 2045 | str_units(), |
2049 | units_per_sector, sector_size, units_per_sector * sector_size | 2046 | units_per_sector, sector_size, units_per_sector * sector_size |
2050 | ); | 2047 | ); |
2051 | } | 2048 | } |
@@ -2486,7 +2483,7 @@ add_partition(int n, int sys) | |||
2486 | for (i = 0; i < g_partitions; i++) | 2483 | for (i = 0; i < g_partitions; i++) |
2487 | first[i] = (cround(first[i]) - 1) * units_per_sector; | 2484 | first[i] = (cround(first[i]) - 1) * units_per_sector; |
2488 | 2485 | ||
2489 | snprintf(mesg, sizeof(mesg), "First %s", str_units(SINGULAR)); | 2486 | snprintf(mesg, sizeof(mesg), "First %s", str_units()); |
2490 | do { | 2487 | do { |
2491 | temp = start; | 2488 | temp = start; |
2492 | for (i = 0; i < g_partitions; i++) { | 2489 | for (i = 0; i < g_partitions; i++) { |
@@ -2548,7 +2545,7 @@ add_partition(int n, int sys) | |||
2548 | } else { | 2545 | } else { |
2549 | snprintf(mesg, sizeof(mesg), | 2546 | snprintf(mesg, sizeof(mesg), |
2550 | "Last %s or +size{,K,M,G,T}", | 2547 | "Last %s or +size{,K,M,G,T}", |
2551 | str_units(SINGULAR) | 2548 | str_units() |
2552 | ); | 2549 | ); |
2553 | stop = read_int(cround(start), cround(limit), cround(limit), cround(start), mesg); | 2550 | stop = read_int(cround(start), cround(limit), cround(limit), cround(start), mesg); |
2554 | if (display_in_cyl_units) { | 2551 | if (display_in_cyl_units) { |
diff --git a/util-linux/fdisk_aix.c b/util-linux/fdisk_aix.c index ee5df50e5..0a5e818fe 100644 --- a/util-linux/fdisk_aix.c +++ b/util-linux/fdisk_aix.c | |||
@@ -6,10 +6,10 @@ | |||
6 | */ | 6 | */ |
7 | 7 | ||
8 | typedef struct { | 8 | typedef struct { |
9 | unsigned int magic; /* expect AIX_LABEL_MAGIC */ | 9 | uint32_t magic; /* expect AIX_LABEL_MAGIC */ |
10 | unsigned int fillbytes1[124]; | 10 | uint32_t fillbytes1[124]; |
11 | unsigned int physical_volume_id; | 11 | uint32_t physical_volume_id; |
12 | unsigned int fillbytes2[124]; | 12 | uint32_t fillbytes2[124]; |
13 | } aix_partition; | 13 | } aix_partition; |
14 | 14 | ||
15 | #define AIX_LABEL_MAGIC 0xc9c2d4c1 | 15 | #define AIX_LABEL_MAGIC 0xc9c2d4c1 |
@@ -17,20 +17,18 @@ typedef struct { | |||
17 | #define AIX_INFO_MAGIC 0x00072959 | 17 | #define AIX_INFO_MAGIC 0x00072959 |
18 | #define AIX_INFO_MAGIC_SWAPPED 0x59290700 | 18 | #define AIX_INFO_MAGIC_SWAPPED 0x59290700 |
19 | 19 | ||
20 | #define aixlabel ((aix_partition *)MBRbuffer) | ||
21 | |||
22 | |||
23 | /* | 20 | /* |
24 | Changes: | 21 | * Changes: |
25 | * 1999-03-20 Arnaldo Carvalho de Melo <acme@conectiva.com.br> | 22 | * 1999-03-20 Arnaldo Carvalho de Melo <acme@conectiva.com.br> |
26 | * Internationalization | 23 | * Internationalization |
27 | * | 24 | * |
28 | * 2003-03-20 Phillip Kesling <pkesling@sgi.com> | 25 | * 2003-03-20 Phillip Kesling <pkesling@sgi.com> |
29 | * Some fixes | 26 | * Some fixes |
30 | */ | 27 | */ |
31 | 28 | ||
32 | static smallint aix_other_endian; /* bool */ | 29 | // Write-only vars, unfinished code? |
33 | static smallint aix_volumes = 1; /* max 15 */ | 30 | //static smallint aix_other_endian; /* bool */ |
31 | //static smallint aix_volumes = 1; /* max 15 */ | ||
34 | 32 | ||
35 | /* | 33 | /* |
36 | * only dealing with free blocks here | 34 | * only dealing with free blocks here |
@@ -54,18 +52,20 @@ aix_info(void) | |||
54 | static int | 52 | static int |
55 | check_aix_label(void) | 53 | check_aix_label(void) |
56 | { | 54 | { |
55 | aix_partition *aixlabel = (void*)MBRbuffer; | ||
56 | |||
57 | if (aixlabel->magic != AIX_LABEL_MAGIC | 57 | if (aixlabel->magic != AIX_LABEL_MAGIC |
58 | && aixlabel->magic != AIX_LABEL_MAGIC_SWAPPED | 58 | && aixlabel->magic != AIX_LABEL_MAGIC_SWAPPED |
59 | ) { | 59 | ) { |
60 | current_label_type = 0; | 60 | current_label_type = LABEL_DOS; |
61 | aix_other_endian = 0; | 61 | // aix_other_endian = 0; |
62 | return 0; | 62 | return 0; |
63 | } | 63 | } |
64 | aix_other_endian = (aixlabel->magic == AIX_LABEL_MAGIC_SWAPPED); | 64 | // aix_other_endian = (aixlabel->magic == AIX_LABEL_MAGIC_SWAPPED); |
65 | update_units(); | 65 | update_units(); |
66 | current_label_type = LABEL_AIX; | 66 | current_label_type = LABEL_AIX; |
67 | g_partitions = 1016; | 67 | g_partitions = 1016; |
68 | aix_volumes = 15; | 68 | // aix_volumes = 15; |
69 | aix_info(); | 69 | aix_info(); |
70 | /*aix_nolabel();*/ /* %% */ | 70 | /*aix_nolabel();*/ /* %% */ |
71 | /*aix_label = 1;*/ /* %% */ | 71 | /*aix_label = 1;*/ /* %% */ |
diff --git a/util-linux/fdisk_gpt.c b/util-linux/fdisk_gpt.c index dbe889f7c..e884e3dc1 100644 --- a/util-linux/fdisk_gpt.c +++ b/util-linux/fdisk_gpt.c | |||
@@ -161,7 +161,7 @@ check_gpt_label(void) | |||
161 | if (!valid_part_table_flag(MBRbuffer) | 161 | if (!valid_part_table_flag(MBRbuffer) |
162 | || first->sys_ind != LEGACY_GPT_TYPE | 162 | || first->sys_ind != LEGACY_GPT_TYPE |
163 | ) { | 163 | ) { |
164 | current_label_type = 0; | 164 | current_label_type = LABEL_DOS; |
165 | return 0; | 165 | return 0; |
166 | } | 166 | } |
167 | 167 | ||
@@ -171,7 +171,7 @@ check_gpt_label(void) | |||
171 | gpt_hdr = (void *)pe.sectorbuffer; | 171 | gpt_hdr = (void *)pe.sectorbuffer; |
172 | 172 | ||
173 | if (gpt_hdr->magic != SWAP_LE64(GPT_MAGIC)) { | 173 | if (gpt_hdr->magic != SWAP_LE64(GPT_MAGIC)) { |
174 | current_label_type = 0; | 174 | current_label_type = LABEL_DOS; |
175 | return 0; | 175 | return 0; |
176 | } | 176 | } |
177 | 177 | ||
@@ -194,7 +194,7 @@ check_gpt_label(void) | |||
194 | || SWAP_LE32(gpt_hdr->hdr_size) > sector_size | 194 | || SWAP_LE32(gpt_hdr->hdr_size) > sector_size |
195 | ) { | 195 | ) { |
196 | puts("\nwarning: unable to parse GPT disklabel\n"); | 196 | puts("\nwarning: unable to parse GPT disklabel\n"); |
197 | current_label_type = 0; | 197 | current_label_type = LABEL_DOS; |
198 | return 0; | 198 | return 0; |
199 | } | 199 | } |
200 | 200 | ||
diff --git a/util-linux/fdisk_osf.c b/util-linux/fdisk_osf.c index 1328c1fcd..92180b2bc 100644 --- a/util-linux/fdisk_osf.c +++ b/util-linux/fdisk_osf.c | |||
@@ -470,7 +470,7 @@ xbsd_new_part(void) | |||
470 | end = xbsd_dlabel.d_secperunit - 1; | 470 | end = xbsd_dlabel.d_secperunit - 1; |
471 | #endif | 471 | #endif |
472 | 472 | ||
473 | snprintf(mesg, sizeof(mesg), "First %s", str_units(SINGULAR)); | 473 | snprintf(mesg, sizeof(mesg), "First %s", str_units()); |
474 | begin = read_int(bsd_cround(begin), bsd_cround(begin), bsd_cround(end), | 474 | begin = read_int(bsd_cround(begin), bsd_cround(begin), bsd_cround(end), |
475 | 0, mesg); | 475 | 0, mesg); |
476 | 476 | ||
@@ -478,7 +478,7 @@ xbsd_new_part(void) | |||
478 | begin = (begin - 1) * xbsd_dlabel.d_secpercyl; | 478 | begin = (begin - 1) * xbsd_dlabel.d_secpercyl; |
479 | 479 | ||
480 | snprintf(mesg, sizeof(mesg), "Last %s or +size or +sizeM or +sizeK", | 480 | snprintf(mesg, sizeof(mesg), "Last %s or +size or +sizeM or +sizeK", |
481 | str_units(SINGULAR)); | 481 | str_units()); |
482 | end = read_int(bsd_cround(begin), bsd_cround(end), bsd_cround(end), | 482 | end = read_int(bsd_cround(begin), bsd_cround(end), bsd_cround(end), |
483 | bsd_cround(begin), mesg); | 483 | bsd_cround(begin), mesg); |
484 | 484 | ||
diff --git a/util-linux/fdisk_sgi.c b/util-linux/fdisk_sgi.c index 0e5491a19..c90c801e2 100644 --- a/util-linux/fdisk_sgi.c +++ b/util-linux/fdisk_sgi.c | |||
@@ -295,19 +295,19 @@ sgi_list_table(int xtra) | |||
295 | "%u cylinders, %u physical cylinders\n" | 295 | "%u cylinders, %u physical cylinders\n" |
296 | "%u extra sects/cyl, interleave %u:1\n" | 296 | "%u extra sects/cyl, interleave %u:1\n" |
297 | "%s\n" | 297 | "%s\n" |
298 | "Units = %s of %u * 512 bytes\n\n", | 298 | "Units = %ss of %u * 512 bytes\n\n", |
299 | disk_device, g_heads, g_sectors, g_cylinders, | 299 | disk_device, g_heads, g_sectors, g_cylinders, |
300 | SGI_SSWAP16(sgiparam.pcylcount), | 300 | SGI_SSWAP16(sgiparam.pcylcount), |
301 | SGI_SSWAP16(sgiparam.sparecyl), | 301 | SGI_SSWAP16(sgiparam.sparecyl), |
302 | SGI_SSWAP16(sgiparam.ilfact), | 302 | SGI_SSWAP16(sgiparam.ilfact), |
303 | (char *)sgilabel, | 303 | (char *)sgilabel, |
304 | str_units(PLURAL), units_per_sector); | 304 | str_units(), units_per_sector); |
305 | } else { | 305 | } else { |
306 | printf("\nDisk %s (SGI disk label): " | 306 | printf("\nDisk %s (SGI disk label): " |
307 | "%u heads, %u sectors, %u cylinders\n" | 307 | "%u heads, %u sectors, %u cylinders\n" |
308 | "Units = %s of %u * 512 bytes\n\n", | 308 | "Units = %ss of %u * 512 bytes\n\n", |
309 | disk_device, g_heads, g_sectors, g_cylinders, | 309 | disk_device, g_heads, g_sectors, g_cylinders, |
310 | str_units(PLURAL), units_per_sector ); | 310 | str_units(), units_per_sector ); |
311 | } | 311 | } |
312 | 312 | ||
313 | w = strlen(disk_device); | 313 | w = strlen(disk_device); |
@@ -720,7 +720,7 @@ sgi_add_partition(int n, int sys) | |||
720 | printf("You got a partition overlap on the disk. Fix it first!\n"); | 720 | printf("You got a partition overlap on the disk. Fix it first!\n"); |
721 | return; | 721 | return; |
722 | } | 722 | } |
723 | snprintf(mesg, sizeof(mesg), "First %s", str_units(SINGULAR)); | 723 | snprintf(mesg, sizeof(mesg), "First %s", str_units()); |
724 | while (1) { | 724 | while (1) { |
725 | if (sys == SGI_VOLUME) { | 725 | if (sys == SGI_VOLUME) { |
726 | last = sgi_get_lastblock(); | 726 | last = sgi_get_lastblock(); |
@@ -746,7 +746,7 @@ sgi_add_partition(int n, int sys) | |||
746 | printf("You will get a partition overlap on the disk. " | 746 | printf("You will get a partition overlap on the disk. " |
747 | "Fix it first!\n"); | 747 | "Fix it first!\n"); |
748 | } | 748 | } |
749 | snprintf(mesg, sizeof(mesg), " Last %s", str_units(SINGULAR)); | 749 | snprintf(mesg, sizeof(mesg), " Last %s", str_units()); |
750 | last = read_int(scround(first), scround(last)-1, scround(last)-1, | 750 | last = read_int(scround(first), scround(last)-1, scround(last)-1, |
751 | scround(first), mesg)+1; | 751 | scround(first), mesg)+1; |
752 | if (display_in_cyl_units) | 752 | if (display_in_cyl_units) |
diff --git a/util-linux/fdisk_sun.c b/util-linux/fdisk_sun.c index 3697a69b9..29d7c283a 100644 --- a/util-linux/fdisk_sun.c +++ b/util-linux/fdisk_sun.c | |||
@@ -491,7 +491,7 @@ add_sun_partition(int n, int sys) | |||
491 | return; | 491 | return; |
492 | } | 492 | } |
493 | } | 493 | } |
494 | snprintf(mesg, sizeof(mesg), "First %s", str_units(SINGULAR)); | 494 | snprintf(mesg, sizeof(mesg), "First %s", str_units()); |
495 | while (1) { | 495 | while (1) { |
496 | if (whole_disk) | 496 | if (whole_disk) |
497 | first = read_int(0, 0, 0, 0, mesg); | 497 | first = read_int(0, 0, 0, 0, mesg); |
@@ -546,7 +546,7 @@ and is of type 'Whole disk'\n"); | |||
546 | } | 546 | } |
547 | snprintf(mesg, sizeof(mesg), | 547 | snprintf(mesg, sizeof(mesg), |
548 | "Last %s or +size or +sizeM or +sizeK", | 548 | "Last %s or +size or +sizeM or +sizeK", |
549 | str_units(SINGULAR)); | 549 | str_units()); |
550 | if (whole_disk) | 550 | if (whole_disk) |
551 | last = read_int(scround(stop2), scround(stop2), scround(stop2), | 551 | last = read_int(scround(stop2), scround(stop2), scround(stop2), |
552 | 0, mesg); | 552 | 0, mesg); |
@@ -567,8 +567,8 @@ and is of type 'Whole disk'\n"); | |||
567 | "You haven't covered the whole disk with the 3rd partition,\n" | 567 | "You haven't covered the whole disk with the 3rd partition,\n" |
568 | "but your value %u %s covers some other partition.\n" | 568 | "but your value %u %s covers some other partition.\n" |
569 | "Your entry has been changed to %u %s\n", | 569 | "Your entry has been changed to %u %s\n", |
570 | scround(last), str_units(SINGULAR), | 570 | scround(last), str_units(), |
571 | scround(stop), str_units(SINGULAR)); | 571 | scround(stop), str_units()); |
572 | last = stop; | 572 | last = stop; |
573 | } | 573 | } |
574 | } else if (!whole_disk && last > stop) | 574 | } else if (!whole_disk && last > stop) |
@@ -636,20 +636,20 @@ sun_list_table(int xtra) | |||
636 | "%u cylinders, %u alternate cylinders, %u physical cylinders\n" | 636 | "%u cylinders, %u alternate cylinders, %u physical cylinders\n" |
637 | "%u extra sects/cyl, interleave %u:1\n" | 637 | "%u extra sects/cyl, interleave %u:1\n" |
638 | "%s\n" | 638 | "%s\n" |
639 | "Units = %s of %u * 512 bytes\n\n", | 639 | "Units = %ss of %u * 512 bytes\n\n", |
640 | disk_device, g_heads, g_sectors, SUN_SSWAP16(sunlabel->rspeed), | 640 | disk_device, g_heads, g_sectors, SUN_SSWAP16(sunlabel->rspeed), |
641 | g_cylinders, SUN_SSWAP16(sunlabel->nacyl), | 641 | g_cylinders, SUN_SSWAP16(sunlabel->nacyl), |
642 | SUN_SSWAP16(sunlabel->pcylcount), | 642 | SUN_SSWAP16(sunlabel->pcylcount), |
643 | SUN_SSWAP16(sunlabel->sparecyl), | 643 | SUN_SSWAP16(sunlabel->sparecyl), |
644 | SUN_SSWAP16(sunlabel->ilfact), | 644 | SUN_SSWAP16(sunlabel->ilfact), |
645 | (char *)sunlabel, | 645 | (char *)sunlabel, |
646 | str_units(PLURAL), units_per_sector); | 646 | str_units(), units_per_sector); |
647 | else | 647 | else |
648 | printf( | 648 | printf( |
649 | "\nDisk %s (Sun disk label): %u heads, %u sectors, %u cylinders\n" | 649 | "\nDisk %s (Sun disk label): %u heads, %u sectors, %u cylinders\n" |
650 | "Units = %s of %u * 512 bytes\n\n", | 650 | "Units = %ss of %u * 512 bytes\n\n", |
651 | disk_device, g_heads, g_sectors, g_cylinders, | 651 | disk_device, g_heads, g_sectors, g_cylinders, |
652 | str_units(PLURAL), units_per_sector); | 652 | str_units(), units_per_sector); |
653 | 653 | ||
654 | printf("%*s Flag Start End Blocks Id System\n", | 654 | printf("%*s Flag Start End Blocks Id System\n", |
655 | w + 1, "Device"); | 655 | w + 1, "Device"); |
diff --git a/util-linux/rdate.c b/util-linux/rdate.c index 41aade5ea..bb1dc519a 100644 --- a/util-linux/rdate.c +++ b/util-linux/rdate.c | |||
@@ -95,9 +95,13 @@ int rdate_main(int argc UNUSED_PARAM, char **argv) | |||
95 | if (!(flags & 2)) { /* no -p (-s may be present) */ | 95 | if (!(flags & 2)) { /* no -p (-s may be present) */ |
96 | if (time(NULL) == remote_time) | 96 | if (time(NULL) == remote_time) |
97 | bb_simple_error_msg("current time matches remote time"); | 97 | bb_simple_error_msg("current time matches remote time"); |
98 | else | 98 | else { |
99 | if (stime(&remote_time) < 0) | 99 | struct timespec ts; |
100 | ts.tv_sec = remote_time; | ||
101 | ts.tv_nsec = 0; | ||
102 | if (clock_settime(CLOCK_REALTIME, &ts) < 0) | ||
100 | bb_simple_perror_msg_and_die("can't set time of day"); | 103 | bb_simple_perror_msg_and_die("can't set time of day"); |
104 | } | ||
101 | } | 105 | } |
102 | 106 | ||
103 | if (flags != 1) /* not lone -s */ | 107 | if (flags != 1) /* not lone -s */ |
diff --git a/util-linux/taskset.c b/util-linux/taskset.c index ed8878ad4..b542f8c83 100644 --- a/util-linux/taskset.c +++ b/util-linux/taskset.c | |||
@@ -20,6 +20,14 @@ | |||
20 | //config: Needed for machines with more than 32-64 CPUs: | 20 | //config: Needed for machines with more than 32-64 CPUs: |
21 | //config: affinity parameter 0xHHHHHHHHHHHHHHHHHHHH can be arbitrarily long | 21 | //config: affinity parameter 0xHHHHHHHHHHHHHHHHHHHH can be arbitrarily long |
22 | //config: in this case. Otherwise, it is limited to sizeof(long). | 22 | //config: in this case. Otherwise, it is limited to sizeof(long). |
23 | //config: | ||
24 | //config:config FEATURE_TASKSET_CPULIST | ||
25 | //config: bool "CPU list support (-c option)" | ||
26 | //config: default y | ||
27 | //config: depends on FEATURE_TASKSET_FANCY | ||
28 | //config: help | ||
29 | //config: Add support for taking/printing affinity as CPU list when '-c' | ||
30 | //config: option is used. For example, it prints '0-3,7' instead of mask '8f'. | ||
23 | 31 | ||
24 | //applet:IF_TASKSET(APPLET_NOEXEC(taskset, taskset, BB_DIR_USR_BIN, BB_SUID_DROP, taskset)) | 32 | //applet:IF_TASKSET(APPLET_NOEXEC(taskset, taskset, BB_DIR_USR_BIN, BB_SUID_DROP, taskset)) |
25 | 33 | ||
@@ -108,26 +116,120 @@ static unsigned long *get_aff(int pid, unsigned *sz) | |||
108 | return mask; | 116 | return mask; |
109 | } | 117 | } |
110 | 118 | ||
119 | #if ENABLE_FEATURE_TASKSET_CPULIST | ||
120 | /* | ||
121 | * Parse the CPU list and set the mask accordingly. | ||
122 | * | ||
123 | * The list element can be either a CPU index or a range of CPU indices. | ||
124 | * Example: "1,3,5-7". Stride can be specified: "0-7:2" is "0,2,4,6". | ||
125 | * Note: leading and trailing whitespace is not allowed. | ||
126 | * util-linux 2.31 allows leading and sometimes trailing whitespace: | ||
127 | * ok: taskset -c ' 1, 2' | ||
128 | * ok: taskset -c ' 1 , 2' | ||
129 | * ok: taskset -c ' 1-7: 2 ,8' | ||
130 | * not ok: taskset -c ' 1 ' | ||
131 | * not ok: taskset -c ' 1-7: 2 ' | ||
132 | */ | ||
133 | static void parse_cpulist(ul *mask, unsigned max, char *s) | ||
134 | { | ||
135 | char *aff = s; | ||
136 | for (;;) { | ||
137 | unsigned bit, end; | ||
138 | unsigned stride = 1; | ||
139 | |||
140 | bit = end = bb_strtou(s, &s, 10); | ||
141 | if (*s == '-') { | ||
142 | s++; | ||
143 | end = bb_strtou(s, &s, 10); | ||
144 | if (*s == ':') { | ||
145 | s++; | ||
146 | stride = bb_strtou(s, &s, 10); | ||
147 | } | ||
148 | } | ||
149 | if ((*s != ',' && *s != '\0') | ||
150 | || bit > end | ||
151 | || end == UINT_MAX /* bb_strtou returns this on malformed / ERANGE numbers */ | ||
152 | || (stride - 1) > (UINT_MAX / 4) | ||
153 | /* disallow 0, malformed input, and too large stride prone to overflows */ | ||
154 | ) { | ||
155 | bb_error_msg_and_die("bad affinity '%s'", aff); | ||
156 | } | ||
157 | while (bit <= end && bit < max) { | ||
158 | mask[bit / BITS_UL] |= (1UL << (bit & MASK_UL)); | ||
159 | bit += stride; | ||
160 | } | ||
161 | if (*s == '\0') | ||
162 | break; | ||
163 | s++; | ||
164 | } | ||
165 | } | ||
166 | static void print_cpulist(const ul *mask, unsigned mask_size_in_bytes) | ||
167 | { | ||
168 | const ul *mask_end; | ||
169 | const char *delim; | ||
170 | unsigned pos; | ||
171 | ul bit; | ||
172 | |||
173 | mask_end = mask + mask_size_in_bytes / sizeof(mask[0]); | ||
174 | delim = ""; | ||
175 | pos = 0; | ||
176 | bit = 1; | ||
177 | for (;;) { | ||
178 | if (*mask & bit) { | ||
179 | unsigned onebit = pos + 1; | ||
180 | printf("%s%u", delim, pos); | ||
181 | do { | ||
182 | pos++; | ||
183 | bit <<= 1; | ||
184 | if (bit == 0) { | ||
185 | mask++; | ||
186 | if (mask >= mask_end) | ||
187 | break; | ||
188 | bit = 1; | ||
189 | } | ||
190 | } while (*mask & bit); | ||
191 | if (onebit != pos) | ||
192 | printf("-%u", pos - 1); | ||
193 | delim = ","; | ||
194 | } | ||
195 | pos++; | ||
196 | bit <<= 1; | ||
197 | if (bit == 0) { | ||
198 | mask++; | ||
199 | if (mask >= mask_end) | ||
200 | break; | ||
201 | bit = 1; | ||
202 | } | ||
203 | } | ||
204 | bb_putchar('\n'); | ||
205 | } | ||
206 | #endif | ||
207 | |||
111 | int taskset_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 208 | int taskset_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
112 | int taskset_main(int argc UNUSED_PARAM, char **argv) | 209 | int taskset_main(int argc UNUSED_PARAM, char **argv) |
113 | { | 210 | { |
114 | ul *mask; | 211 | ul *mask; |
115 | unsigned mask_size_in_bytes; | 212 | unsigned mask_size_in_bytes; |
116 | pid_t pid = 0; | 213 | pid_t pid = 0; |
117 | unsigned opt_p; | ||
118 | const char *current_new; | 214 | const char *current_new; |
119 | char *aff; | 215 | char *aff; |
216 | unsigned opts; | ||
217 | enum { | ||
218 | OPT_p = 1 << 0, | ||
219 | OPT_c = (1 << 1) * ENABLE_FEATURE_TASKSET_CPULIST, | ||
220 | }; | ||
120 | 221 | ||
121 | /* NB: we mimic util-linux's taskset: -p does not take | 222 | /* NB: we mimic util-linux's taskset: -p does not take |
122 | * an argument, i.e., "-pN" is NOT valid, only "-p N"! | 223 | * an argument, i.e., "-pN" is NOT valid, only "-p N"! |
123 | * Indeed, util-linux-2.13-pre7 uses: | 224 | * Indeed, util-linux-2.13-pre7 uses: |
124 | * getopt_long(argc, argv, "+pchV", ...), not "...p:..." */ | 225 | * getopt_long(argc, argv, "+pchV", ...), not "...p:..." */ |
125 | 226 | ||
126 | opt_p = getopt32(argv, "^+" "p" "\0" "-1" /* at least 1 arg */); | 227 | opts = getopt32(argv, "^+" "p"IF_FEATURE_TASKSET_CPULIST("c") |
228 | "\0" "-1" /* at least 1 arg */); | ||
127 | argv += optind; | 229 | argv += optind; |
128 | 230 | ||
129 | aff = *argv++; | 231 | aff = *argv++; |
130 | if (opt_p) { | 232 | if (opts & OPT_p) { |
131 | char *pid_str = aff; | 233 | char *pid_str = aff; |
132 | if (*argv) { /* "-p <aff> <pid> ...rest.is.ignored..." */ | 234 | if (*argv) { /* "-p <aff> <pid> ...rest.is.ignored..." */ |
133 | pid_str = *argv; /* NB: *argv != NULL in this case */ | 235 | pid_str = *argv; /* NB: *argv != NULL in this case */ |
@@ -144,8 +246,14 @@ int taskset_main(int argc UNUSED_PARAM, char **argv) | |||
144 | current_new = "current"; | 246 | current_new = "current"; |
145 | print_aff: | 247 | print_aff: |
146 | mask = get_aff(pid, &mask_size_in_bytes); | 248 | mask = get_aff(pid, &mask_size_in_bytes); |
147 | if (opt_p) { | 249 | if (opts & OPT_p) { |
148 | printf("pid %d's %s affinity mask: "TASKSET_PRINTF_MASK"\n", | 250 | #if ENABLE_FEATURE_TASKSET_CPULIST |
251 | if (opts & OPT_c) { | ||
252 | printf("pid %d's %s affinity list: ", pid, current_new); | ||
253 | print_cpulist(mask, mask_size_in_bytes); | ||
254 | } else | ||
255 | #endif | ||
256 | printf("pid %d's %s affinity mask: "TASKSET_PRINTF_MASK"\n", | ||
149 | pid, current_new, from_mask(mask, mask_size_in_bytes)); | 257 | pid, current_new, from_mask(mask, mask_size_in_bytes)); |
150 | if (*argv == NULL) { | 258 | if (*argv == NULL) { |
151 | /* Either it was just "-p <pid>", | 259 | /* Either it was just "-p <pid>", |
@@ -158,17 +266,27 @@ int taskset_main(int argc UNUSED_PARAM, char **argv) | |||
158 | } | 266 | } |
159 | memset(mask, 0, mask_size_in_bytes); | 267 | memset(mask, 0, mask_size_in_bytes); |
160 | 268 | ||
161 | /* Affinity was specified, translate it into mask */ | ||
162 | /* it is always in hex, skip "0x" if it exists */ | ||
163 | if (aff[0] == '0' && (aff[1]|0x20) == 'x') | ||
164 | aff += 2; | ||
165 | |||
166 | if (!ENABLE_FEATURE_TASKSET_FANCY) { | 269 | if (!ENABLE_FEATURE_TASKSET_FANCY) { |
270 | /* Affinity was specified, translate it into mask */ | ||
271 | /* it is always in hex, skip "0x" if it exists */ | ||
272 | if (aff[0] == '0' && (aff[1]|0x20) == 'x') | ||
273 | aff += 2; | ||
167 | mask[0] = xstrtoul(aff, 16); | 274 | mask[0] = xstrtoul(aff, 16); |
168 | } else { | 275 | } |
276 | #if ENABLE_FEATURE_TASKSET_CPULIST | ||
277 | else if (opts & OPT_c) { | ||
278 | parse_cpulist(mask, mask_size_in_bytes * 8, aff); | ||
279 | } | ||
280 | #endif | ||
281 | else { | ||
169 | unsigned i; | 282 | unsigned i; |
170 | char *last_char; | 283 | char *last_char; |
171 | 284 | ||
285 | /* Affinity was specified, translate it into mask */ | ||
286 | /* it is always in hex, skip "0x" if it exists */ | ||
287 | if (aff[0] == '0' && (aff[1]|0x20) == 'x') | ||
288 | aff += 2; | ||
289 | |||
172 | i = 0; /* bit pos in mask[] */ | 290 | i = 0; /* bit pos in mask[] */ |
173 | 291 | ||
174 | /* aff is ASCII hex string, accept very long masks in this form. | 292 | /* aff is ASCII hex string, accept very long masks in this form. |