Changeset a30e435 in mainline
- Timestamp:
- 2011-04-01T12:00:23Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- ba63912
- Parents:
- 73aec008 (diff), 1e2629f (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- uspace/app/bdsh/cmds/modules/ls
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/bdsh/cmds/modules/ls/ls.c
r73aec008 ra30e435 38 38 #include <dirent.h> 39 39 #include <fcntl.h> 40 #include <getopt.h> 40 41 #include <sys/types.h> 41 42 #include <sys/stat.h> 42 43 #include <str.h> 44 #include <sort.h> 43 45 44 46 #include "errors.h" … … 51 53 static const char *cmdname = "ls"; 52 54 53 static void ls_scan_dir(const char *d, DIR *dirp) 54 { 55 struct dirent *dp; 56 char *buff; 57 55 static struct option const long_options[] = { 56 { "help", no_argument, 0, 'h' }, 57 { "unsort", no_argument, 0, 'u' }, 58 { 0, 0, 0, 0 } 59 }; 60 61 /** Compare 2 directory elements. 62 * 63 * It compares 2 elements of a directory : a file is considered 64 * as lower than a directory, and if they have the same type, 65 * they are compared alphabetically. 66 * 67 * @param a Pointer to the structure of the first element. 68 * @param b Pointer to the structure of the second element. 69 * @param arg Pointer for an other and optionnal argument. 70 * 71 * @return -1 if a < b, 72 * 1 otherwise. 73 */ 74 static int ls_cmp(void *a, void *b, void *arg) 75 { 76 int a_isdir = (*((struct dir_elem_t *)a)).isdir; 77 char * a_name = (*((struct dir_elem_t *)a)).name; 78 79 int b_isdir = (*((struct dir_elem_t *)b)).isdir; 80 char * b_name = (*((struct dir_elem_t *)b)).name; 81 82 if ((!a_isdir && b_isdir) 83 || (((!b_isdir && !a_isdir) || (b_isdir && a_isdir)) 84 && str_cmp(a_name, b_name) < 0)) 85 return -1; 86 else 87 return 1; 88 } 89 90 /** Scan a directory. 91 * 92 * Scan the content of a directory and print it. 93 * 94 * @param d Name of the directory. 95 * @param dirp Directory stream. 96 * @param sort 1 if the output must be sorted, 97 * 0 otherwise. 98 */ 99 static void ls_scan_dir(const char *d, DIR *dirp, int sort) 100 { 101 int alloc_blocks = 20; 102 int i = 0; 103 int nbdirs = 0; 104 int rc = 0; 105 char * buff = NULL; 106 struct dir_elem_t * tmp = NULL; 107 struct dir_elem_t * tosort = NULL; 108 struct dirent * dp = NULL; 109 struct stat s; 110 58 111 if (! dirp) 59 112 return; … … 64 117 return; 65 118 } 66 119 memset(buff, 0, sizeof(buff)); 120 121 if (!sort) { 122 while ((dp = readdir(dirp))) { 123 memset(buff, 0, sizeof(buff)); 124 /* Don't worry if inserting a double slash, this will be fixed by 125 * absolutize() later with subsequent calls to open() or readdir() */ 126 snprintf(buff, PATH_MAX - 1, "%s/%s", d, dp->d_name); 127 ls_print(dp->d_name, buff); 128 } 129 130 free(buff); 131 132 return; 133 } 134 135 tosort = (struct dir_elem_t *)malloc(alloc_blocks*sizeof(struct dir_elem_t)); 136 if (NULL == tosort) { 137 cli_error(CL_ENOMEM, "ls: failed to scan %s", d); 138 free(buff); 139 return; 140 } 141 memset(tosort, 0, sizeof(tosort)); 142 67 143 while ((dp = readdir(dirp))) { 144 nbdirs++; 145 146 if (nbdirs > alloc_blocks) { 147 alloc_blocks += alloc_blocks; 148 149 tmp = (struct dir_elem_t *)realloc(tosort, 150 alloc_blocks*sizeof(struct dir_elem_t)); 151 if (NULL == tmp) { 152 cli_error(CL_ENOMEM, "ls: failed to scan %s", d); 153 for(i=0;i<(nbdirs-1);i++) { 154 free(tosort[i].name); 155 } 156 free(tosort); 157 free(buff); 158 return; 159 } 160 161 tosort = tmp; 162 } 163 164 // fill the name field 165 tosort[nbdirs-1].name = (char *)malloc(str_length(dp->d_name)+1); 166 if (NULL == tosort[nbdirs-1].name) { 167 cli_error(CL_ENOMEM, "ls: failed to scan %s", d); 168 for(i=0;i<(nbdirs-1);i++) { 169 free(tosort[i].name); 170 } 171 free(tosort); 172 free(buff); 173 return; 174 } 175 176 memset(tosort[nbdirs-1].name, 0, str_length(dp->d_name)+1); 177 str_cpy(tosort[nbdirs-1].name, str_length(dp->d_name)+1, dp->d_name); 178 179 // fill the isdir field 180 memset(buff, 0, sizeof(buff)); 181 snprintf(buff, PATH_MAX - 1, "%s/%s", d, tosort[nbdirs-1].name); 182 183 rc = stat(buff, &s); 184 if (rc != 0) { 185 printf("ls: skipping bogus node %s\n", buff); 186 printf("rc=%d\n", rc); 187 for(i=0;i<nbdirs;i++) { 188 free(tosort[i].name); 189 } 190 free(tosort); 191 free(buff); 192 return; 193 } 194 195 tosort[nbdirs-1].isdir = s.is_directory ? 1 : 0; 196 } 197 198 if (!qsort(&tosort[0], nbdirs, sizeof(struct dir_elem_t), ls_cmp, NULL)) { 199 printf("Sorting error.\n"); 200 } 201 202 for(i=0;i<nbdirs;i++) { 68 203 memset(buff, 0, sizeof(buff)); 69 204 /* Don't worry if inserting a double slash, this will be fixed by 70 205 * absolutize() later with subsequent calls to open() or readdir() */ 71 snprintf(buff, PATH_MAX - 1, "%s/%s", d, dp->d_name); 72 ls_print(dp->d_name, buff); 73 } 74 206 snprintf(buff, PATH_MAX - 1, "%s/%s", d, tosort[i].name); 207 ls_print(tosort[i].name, buff); 208 free(tosort[i].name); 209 } 210 211 free(tosort); 75 212 free(buff); 76 213 … … 78 215 } 79 216 80 /* ls_print currently does nothing more than print the entry. 81 * in the future, we will likely pass the absolute path, and 217 /** Print an entry. 218 * 219 * ls_print currently does nothing more than print the entry. 220 * In the future, we will likely pass the absolute path, and 82 221 * some sort of ls_options structure that controls how each 83 222 * entry is printed and what is printed about it. 84 223 * 85 * Now we just print basic DOS style lists */ 86 224 * Now we just print basic DOS style lists. 225 * 226 * @param name Name of the entry. 227 * @param pathname Path of the entry. 228 */ 87 229 static void ls_print(const char *name, const char *pathname) 88 230 { … … 114 256 } else { 115 257 help_cmd_ls(HELP_SHORT); 116 printf(" `%s' [path], if no path is given the current " 117 "working directory is used.\n", cmdname); 258 printf( 259 "Usage: %s [options] [path]\n" 260 "If not path is given, the current working directory is used.\n" 261 "Options:\n" 262 " -h, --help A short option summary\n" 263 " -u, --unsort Do not sort directory entries\n", 264 cmdname); 118 265 } 119 266 … … 127 274 char *buff; 128 275 DIR *dirp; 276 int c, opt_ind; 277 int sort = 1; 129 278 130 279 argc = cli_count_args(argv); 131 280 281 for (c = 0, optind = 0, opt_ind = 0; c != -1;) { 282 c = getopt_long(argc, argv, "hu", long_options, &opt_ind); 283 switch (c) { 284 case 'h': 285 help_cmd_ls(HELP_LONG); 286 return CMD_SUCCESS; 287 case 'u': 288 sort = 0; 289 break; 290 } 291 } 292 293 int dir = (int)argc > optind ? (int)argc-1 : optind-1; 294 argc -= (optind-1); 295 132 296 buff = (char *) malloc(PATH_MAX); 133 297 if (NULL == buff) { … … 136 300 } 137 301 memset(buff, 0, sizeof(buff)); 138 302 139 303 if (argc == 1) 140 304 getcwd(buff, PATH_MAX); 141 305 else 142 str_cpy(buff, PATH_MAX, argv[ 1]);143 306 str_cpy(buff, PATH_MAX, argv[dir]); 307 144 308 if (stat(buff, &s)) { 145 309 cli_error(CL_ENOENT, buff); … … 158 322 return CMD_FAILURE; 159 323 } 160 ls_scan_dir(buff, dirp );324 ls_scan_dir(buff, dirp, sort); 161 325 closedir(dirp); 162 326 } -
uspace/app/bdsh/cmds/modules/ls/ls.h
r73aec008 ra30e435 7 7 #define LS_DIR 2 8 8 9 static void ls_scan_dir(const char *, DIR * );9 static void ls_scan_dir(const char *, DIR *, int); 10 10 static void ls_print(const char *, const char *); 11 12 /** Structure to represent a directory entry. 13 * 14 * Useful to keep together important informations 15 * for sorting directory entries. 16 */ 17 struct dir_elem_t { 18 char * name; 19 int isdir; 20 }; 11 21 12 22 #endif /* LS_H */
Note:
See TracChangeset
for help on using the changeset viewer.