aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2009-03-21 19:11:23 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2009-03-21 19:11:23 +0000
commit3a014b85dc57a88b5e1eb006a2fa3062f4bebc8f (patch)
tree6befbfaa357218f40a809dc6135f621e0f2fc365
parent05af832097848cbc0656e687fc4a07525c2de513 (diff)
downloadbusybox-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.c198
-rw-r--r--libbb/xreadlink.c6
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,
76LIST_ID_NUMERIC = 1 << 5, 76LIST_ID_NUMERIC = 1 << 5,
77LIST_CONTEXT = 1 << 6, 77LIST_CONTEXT = 1 << 6,
78LIST_SIZE = 1 << 7, 78LIST_SIZE = 1 << 7,
79LIST_DEV = 1 << 8, 79//LIST_DEV = 1 << 8, - unused, synonym to LIST_SIZE
80LIST_DATE_TIME = 1 << 9, 80LIST_DATE_TIME = 1 << 9,
81LIST_FULLTIME = 1 << 10, 81LIST_FULLTIME = 1 << 10,
82LIST_FILENAME = 1 << 11, 82LIST_FILENAME = 1 << 11,
@@ -741,8 +741,8 @@ static int print_name(const char *name)
741 741
742static int list_single(const struct dnode *dn) 742static 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}