diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2009-03-21 19:11:23 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2009-03-21 19:11:23 +0000 |
commit | 3a014b85dc57a88b5e1eb006a2fa3062f4bebc8f (patch) | |
tree | 6befbfaa357218f40a809dc6135f621e0f2fc365 | |
parent | 05af832097848cbc0656e687fc4a07525c2de513 (diff) | |
download | busybox-w32-3a014b85dc57a88b5e1eb006a2fa3062f4bebc8f.tar.gz busybox-w32-3a014b85dc57a88b5e1eb006a2fa3062f4bebc8f.tar.bz2 busybox-w32-3a014b85dc57a88b5e1eb006a2fa3062f4bebc8f.zip |
ls: make readlink error to not disrupt output (try ls -l /proc/self/fd).
libbb: make xmalloc_readlink_or_warn warning more specific.
function old new delta
xmalloc_readlink_or_warn 33 61 +28
showfiles 1495 1460 -35
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/1 up/down: 28/-35) Total: -7 bytes
-rw-r--r-- | coreutils/ls.c | 198 | ||||
-rw-r--r-- | libbb/xreadlink.c | 6 |
2 files changed, 102 insertions, 102 deletions
diff --git a/coreutils/ls.c b/coreutils/ls.c index 8007f2a2e..85c6729ea 100644 --- a/coreutils/ls.c +++ b/coreutils/ls.c | |||
@@ -76,7 +76,7 @@ LIST_ID_NAME = 1 << 4, | |||
76 | LIST_ID_NUMERIC = 1 << 5, | 76 | LIST_ID_NUMERIC = 1 << 5, |
77 | LIST_CONTEXT = 1 << 6, | 77 | LIST_CONTEXT = 1 << 6, |
78 | LIST_SIZE = 1 << 7, | 78 | LIST_SIZE = 1 << 7, |
79 | LIST_DEV = 1 << 8, | 79 | //LIST_DEV = 1 << 8, - unused, synonym to LIST_SIZE |
80 | LIST_DATE_TIME = 1 << 9, | 80 | LIST_DATE_TIME = 1 << 9, |
81 | LIST_FULLTIME = 1 << 10, | 81 | LIST_FULLTIME = 1 << 10, |
82 | LIST_FILENAME = 1 << 11, | 82 | LIST_FILENAME = 1 << 11, |
@@ -741,8 +741,8 @@ static int print_name(const char *name) | |||
741 | 741 | ||
742 | static int list_single(const struct dnode *dn) | 742 | static int list_single(const struct dnode *dn) |
743 | { | 743 | { |
744 | int i, column = 0; | 744 | int column = 0; |
745 | 745 | char *lpath; | |
746 | #if ENABLE_FEATURE_LS_TIMESTAMPS | 746 | #if ENABLE_FEATURE_LS_TIMESTAMPS |
747 | char *filetime; | 747 | char *filetime; |
748 | time_t ttime, age; | 748 | time_t ttime, age; |
@@ -767,127 +767,123 @@ static int list_single(const struct dnode *dn) | |||
767 | append = append_char(dn->dstat.st_mode); | 767 | append = append_char(dn->dstat.st_mode); |
768 | #endif | 768 | #endif |
769 | 769 | ||
770 | for (i = 0; i <= 31; i++) { | 770 | /* Do readlink early, so that if it fails, error message |
771 | switch (all_fmt & (1 << i)) { | 771 | * does not appear *inside* of the "ls -l" line */ |
772 | case LIST_INO: | 772 | if (all_fmt & LIST_SYMLINK) |
773 | column += printf("%7lu ", (long) dn->dstat.st_ino); | 773 | if (S_ISLNK(dn->dstat.st_mode)) |
774 | break; | 774 | lpath = xmalloc_readlink_or_warn(dn->fullname); |
775 | case LIST_BLOCKS: | 775 | |
776 | column += printf("%4"OFF_FMT"u ", (off_t) dn->dstat.st_blocks >> 1); | 776 | if (all_fmt & LIST_INO) |
777 | break; | 777 | column += printf("%7lu ", (long) dn->dstat.st_ino); |
778 | case LIST_MODEBITS: | 778 | if (all_fmt & LIST_BLOCKS) |
779 | column += printf("%-10s ", (char *) bb_mode_string(dn->dstat.st_mode)); | 779 | column += printf("%4"OFF_FMT"u ", (off_t) dn->dstat.st_blocks >> 1); |
780 | break; | 780 | if (all_fmt & LIST_MODEBITS) |
781 | case LIST_NLINKS: | 781 | column += printf("%-10s ", (char *) bb_mode_string(dn->dstat.st_mode)); |
782 | column += printf("%4lu ", (long) dn->dstat.st_nlink); | 782 | if (all_fmt & LIST_NLINKS) |
783 | break; | 783 | column += printf("%4lu ", (long) dn->dstat.st_nlink); |
784 | case LIST_ID_NAME: | ||
785 | #if ENABLE_FEATURE_LS_USERNAME | 784 | #if ENABLE_FEATURE_LS_USERNAME |
786 | if (option_mask32 & OPT_g) { | 785 | if (all_fmt & LIST_ID_NAME) { |
787 | printf("%-8.8s", | 786 | if (option_mask32 & OPT_g) { |
788 | get_cached_username(dn->dstat.st_uid)); | 787 | column += printf("%-8.8s", |
789 | column += 9; | 788 | get_cached_username(dn->dstat.st_uid)); |
790 | break; | 789 | } else { |
791 | } | 790 | column += printf("%-8.8s %-8.8s", |
792 | printf("%-8.8s %-8.8s", | ||
793 | get_cached_username(dn->dstat.st_uid), | 791 | get_cached_username(dn->dstat.st_uid), |
794 | get_cached_groupname(dn->dstat.st_gid)); | 792 | get_cached_groupname(dn->dstat.st_gid)); |
795 | column += 17; | 793 | } |
796 | break; | 794 | } |
797 | #endif | 795 | #endif |
798 | case LIST_ID_NUMERIC: | 796 | if (all_fmt & LIST_ID_NUMERIC) { |
799 | column += printf("%-8u %-8u", dn->dstat.st_uid, dn->dstat.st_gid); | 797 | if (option_mask32 & OPT_g) |
800 | break; | 798 | column += printf("%-8u", (int) dn->dstat.st_uid); |
801 | case LIST_SIZE: | 799 | else |
802 | case LIST_DEV: | 800 | column += printf("%-8u %-8u", |
803 | if (S_ISBLK(dn->dstat.st_mode) || S_ISCHR(dn->dstat.st_mode)) { | 801 | (int) dn->dstat.st_uid, |
804 | column += printf("%4u, %3u ", (int) major(dn->dstat.st_rdev), | 802 | (int) dn->dstat.st_gid); |
805 | (int) minor(dn->dstat.st_rdev)); | 803 | } |
804 | if (all_fmt & (LIST_SIZE /*|LIST_DEV*/ )) { | ||
805 | if (S_ISBLK(dn->dstat.st_mode) || S_ISCHR(dn->dstat.st_mode)) { | ||
806 | column += printf("%4u, %3u ", | ||
807 | (int) major(dn->dstat.st_rdev), | ||
808 | (int) minor(dn->dstat.st_rdev)); | ||
809 | } else { | ||
810 | if (all_fmt & LS_DISP_HR) { | ||
811 | column += printf("%9s ", | ||
812 | make_human_readable_str(dn->dstat.st_size, 1, 0)); | ||
806 | } else { | 813 | } else { |
807 | if (all_fmt & LS_DISP_HR) { | 814 | column += printf("%9"OFF_FMT"u ", (off_t) dn->dstat.st_size); |
808 | column += printf("%9s ", | ||
809 | make_human_readable_str(dn->dstat.st_size, 1, 0)); | ||
810 | } else { | ||
811 | column += printf("%9"OFF_FMT"u ", (off_t) dn->dstat.st_size); | ||
812 | } | ||
813 | } | 815 | } |
814 | break; | 816 | } |
817 | } | ||
815 | #if ENABLE_FEATURE_LS_TIMESTAMPS | 818 | #if ENABLE_FEATURE_LS_TIMESTAMPS |
816 | case LIST_FULLTIME: | 819 | if (all_fmt & LIST_FULLTIME) |
817 | printf("%24.24s ", filetime); | 820 | column += printf("%24.24s ", filetime); |
818 | column += 25; | 821 | if (all_fmt & LIST_DATE_TIME) |
819 | break; | 822 | if ((all_fmt & LIST_FULLTIME) == 0) { |
820 | case LIST_DATE_TIME: | 823 | /* current_time_t ~== time(NULL) */ |
821 | if ((all_fmt & LIST_FULLTIME) == 0) { | 824 | age = current_time_t - ttime; |
822 | /* current_time_t ~== time(NULL) */ | 825 | printf("%6.6s ", filetime + 4); |
823 | age = current_time_t - ttime; | 826 | if (age < 3600L * 24 * 365 / 2 && age > -15 * 60) { |
824 | printf("%6.6s ", filetime + 4); | 827 | /* hh:mm if less than 6 months old */ |
825 | if (age < 3600L * 24 * 365 / 2 && age > -15 * 60) { | 828 | printf("%5.5s ", filetime + 11); |
826 | /* hh:mm if less than 6 months old */ | 829 | } else { |
827 | printf("%5.5s ", filetime + 11); | 830 | printf(" %4.4s ", filetime + 20); |
828 | } else { | ||
829 | printf(" %4.4s ", filetime + 20); | ||
830 | } | ||
831 | column += 13; | ||
832 | } | 831 | } |
833 | break; | 832 | column += 13; |
833 | } | ||
834 | #endif | 834 | #endif |
835 | #if ENABLE_SELINUX | 835 | #if ENABLE_SELINUX |
836 | case LIST_CONTEXT: | 836 | if (all_fmt & LIST_CONTEXT) { |
837 | column += printf("%-32s ", dn->sid ? dn->sid : "unknown"); | 837 | column += printf("%-32s ", dn->sid ? dn->sid : "unknown"); |
838 | freecon(dn->sid); | 838 | freecon(dn->sid); |
839 | break; | 839 | } |
840 | #endif | 840 | #endif |
841 | case LIST_FILENAME: | 841 | if (all_fmt & LIST_FILENAME) { |
842 | #if ENABLE_FEATURE_LS_COLOR | 842 | #if ENABLE_FEATURE_LS_COLOR |
843 | if (show_color) { | 843 | if (show_color) { |
844 | info.st_mode = 0; /* for fgcolor() */ | 844 | info.st_mode = 0; /* for fgcolor() */ |
845 | lstat(dn->fullname, &info); | 845 | lstat(dn->fullname, &info); |
846 | printf("\033[%u;%um", bold(info.st_mode), | 846 | printf("\033[%u;%um", bold(info.st_mode), |
847 | fgcolor(info.st_mode)); | 847 | fgcolor(info.st_mode)); |
848 | } | 848 | } |
849 | #endif | 849 | #endif |
850 | column += print_name(dn->name); | 850 | column += print_name(dn->name); |
851 | if (show_color) { | 851 | if (show_color) { |
852 | printf("\033[0m"); | 852 | printf("\033[0m"); |
853 | } | 853 | } |
854 | break; | 854 | } |
855 | case LIST_SYMLINK: | 855 | if (all_fmt & LIST_SYMLINK) { |
856 | if (S_ISLNK(dn->dstat.st_mode)) { | 856 | if (S_ISLNK(dn->dstat.st_mode) && lpath) { |
857 | char *lpath = xmalloc_readlink_or_warn(dn->fullname); | 857 | printf(" -> "); |
858 | if (!lpath) break; | ||
859 | printf(" -> "); | ||
860 | #if ENABLE_FEATURE_LS_FILETYPES || ENABLE_FEATURE_LS_COLOR | 858 | #if ENABLE_FEATURE_LS_FILETYPES || ENABLE_FEATURE_LS_COLOR |
861 | #if ENABLE_FEATURE_LS_COLOR | 859 | #if ENABLE_FEATURE_LS_COLOR |
862 | info.st_mode = 0; /* for fgcolor() */ | 860 | info.st_mode = 0; /* for fgcolor() */ |
863 | #endif | 861 | #endif |
864 | if (stat(dn->fullname, &info) == 0) { | 862 | if (stat(dn->fullname, &info) == 0) { |
865 | append = append_char(info.st_mode); | 863 | append = append_char(info.st_mode); |
866 | } | 864 | } |
867 | #endif | 865 | #endif |
868 | #if ENABLE_FEATURE_LS_COLOR | 866 | #if ENABLE_FEATURE_LS_COLOR |
869 | if (show_color) { | 867 | if (show_color) { |
870 | printf("\033[%u;%um", bold(info.st_mode), | 868 | printf("\033[%u;%um", bold(info.st_mode), |
871 | fgcolor(info.st_mode)); | 869 | fgcolor(info.st_mode)); |
872 | } | 870 | } |
873 | #endif | 871 | #endif |
874 | column += print_name(lpath) + 4; | 872 | column += print_name(lpath) + 4; |
875 | if (show_color) { | 873 | if (show_color) { |
876 | printf("\033[0m"); | 874 | printf("\033[0m"); |
877 | } | ||
878 | free(lpath); | ||
879 | } | 875 | } |
880 | break; | 876 | free(lpath); |
877 | } | ||
878 | } | ||
881 | #if ENABLE_FEATURE_LS_FILETYPES | 879 | #if ENABLE_FEATURE_LS_FILETYPES |
882 | case LIST_FILETYPE: | 880 | if (all_fmt & LIST_FILETYPE) { |
883 | if (append) { | 881 | if (append) { |
884 | putchar(append); | 882 | putchar(append); |
885 | column++; | 883 | column++; |
886 | } | ||
887 | break; | ||
888 | #endif | ||
889 | } | 884 | } |
890 | } | 885 | } |
886 | #endif | ||
891 | 887 | ||
892 | return column; | 888 | return column; |
893 | } | 889 | } |
diff --git a/libbb/xreadlink.c b/libbb/xreadlink.c index 6bff4beae..8d232f16b 100644 --- a/libbb/xreadlink.c +++ b/libbb/xreadlink.c | |||
@@ -91,7 +91,11 @@ char* FAST_FUNC xmalloc_readlink_or_warn(const char *path) | |||
91 | char *buf = xmalloc_readlink(path); | 91 | char *buf = xmalloc_readlink(path); |
92 | if (!buf) { | 92 | if (!buf) { |
93 | /* EINVAL => "file: Invalid argument" => puzzled user */ | 93 | /* EINVAL => "file: Invalid argument" => puzzled user */ |
94 | bb_error_msg("%s: cannot read link (not a symlink?)", path); | 94 | const char *errmsg = "not a symlink"; |
95 | int err = errno; | ||
96 | if (err != EINVAL) | ||
97 | errmsg = strerror(err); | ||
98 | bb_error_msg("%s: cannot read link: %s", path, errmsg); | ||
95 | } | 99 | } |
96 | return buf; | 100 | return buf; |
97 | } | 101 | } |