Changes in uspace/app/bdsh/cmds/modules/cat/cat.c [9d58539:a33706e] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/bdsh/cmds/modules/cat/cat.c
r9d58539 ra33706e 52 52 #define CAT_VERSION "0.0.1" 53 53 #define CAT_DEFAULT_BUFLEN 1024 54 55 static const char *cat_oops = "That option is not yet supported\n"; 54 #define CAT_FULL_FILE 0 55 56 56 static const char *hexchars = "0123456789abcdef"; 57 57 … … 62 62 static sysarg_t console_rows = 0; 63 63 static bool should_quit = false; 64 static bool dash_represents_stdin = false; 64 65 65 66 static console_ctrl_t *console = NULL; … … 73 74 { "more", no_argument, 0, 'm' }, 74 75 { "hex", no_argument, 0, 'x' }, 76 { "stdin", no_argument, 0, 's' }, 75 77 { 0, 0, 0, 0 } 76 78 }; … … 93 95 " -m, --more Pause after each screen full\n" 94 96 " -x, --hex Print bytes as hex values\n" 97 " -s --stdin Treat `-' in file list as standard input\n" 95 98 "Currently, %s is under development, some options don't work.\n", 96 99 cmdname, cmdname); … … 163 166 } 164 167 165 static unsigned int cat_file(const char *fname, size_t blen, bool hex) 168 static unsigned int cat_file(const char *fname, size_t blen, bool hex, 169 off64_t head, off64_t tail, bool tail_first) 166 170 { 167 171 int fd, bytes = 0, count = 0, reads = 0; 168 172 char *buff = NULL; 169 173 int i; 170 size_t offset = 0; 171 172 fd = open(fname, O_RDONLY); 174 size_t offset = 0, copied_bytes = 0; 175 off64_t file_size = 0, length = 0; 176 177 bool reading_stdin = dash_represents_stdin && (str_cmp(fname, "-") == 0); 178 179 if (reading_stdin) { 180 fd = fileno(stdin); 181 /* Allow storing the whole UTF-8 character. */ 182 blen = STR_BOUNDS(1); 183 } else { 184 fd = open(fname, O_RDONLY); 185 } 173 186 if (fd < 0) { 174 187 printf("Unable to open %s\n", fname); … … 183 196 } 184 197 198 if (tail != CAT_FULL_FILE) { 199 file_size = lseek(fd, 0, SEEK_END); 200 if (head == CAT_FULL_FILE) { 201 head = file_size; 202 length = tail; 203 } else if (tail_first) { 204 length = head; 205 } else { 206 if (tail > head) 207 tail = head; 208 length = tail; 209 } 210 211 if (tail_first) { 212 lseek(fd, (tail >= file_size) ? 0 : (file_size - tail), SEEK_SET); 213 } else { 214 lseek(fd, ((head - tail) >= file_size) ? 0 : (head - tail), SEEK_SET); 215 } 216 } else 217 length = head; 218 185 219 do { 186 bytes = read(fd, buff, blen); 220 size_t bytes_to_read; 221 if (reading_stdin) { 222 bytes_to_read = 1; 223 } else { 224 if ((length != CAT_FULL_FILE) 225 && (length - (off64_t)count <= (off64_t)(blen - copied_bytes))) { 226 bytes_to_read = (size_t) (length - count); 227 } else { 228 bytes_to_read = blen - copied_bytes; 229 } 230 } 231 bytes = read(fd, buff + copied_bytes, bytes_to_read); 232 bytes += copied_bytes; 233 copied_bytes = 0; 234 187 235 if (bytes > 0) { 188 count += bytes;189 236 buff[bytes] = '\0'; 190 237 offset = 0; … … 193 240 paged_char(hexchars[((uint8_t)buff[i])/16]); 194 241 paged_char(hexchars[((uint8_t)buff[i])%16]); 242 paged_char(((count+i+1) & 0xf) == 0 ? '\n' : ' '); 195 243 } 196 244 else { … … 199 247 /* Reached end of string */ 200 248 break; 249 } else if (c == U_SPECIAL && offset + 2 >= (size_t)bytes) { 250 /* If an extended character is cut off due to the size of the buffer, 251 we will copy it over to the next buffer so it can be read correctly. */ 252 copied_bytes = bytes - offset + 1; 253 memcpy(buff, buff + offset - 1, copied_bytes); 254 break; 201 255 } 202 256 paged_char(c); … … 204 258 205 259 } 260 count += bytes; 206 261 reads++; 207 262 } 208 } while (bytes > 0 && !should_quit); 263 264 if (reading_stdin) { 265 fflush(stdout); 266 } 267 } while (bytes > 0 && !should_quit && (count < length || length == CAT_FULL_FILE)); 209 268 210 269 close(fd); … … 223 282 int cmd_cat(char **argv) 224 283 { 225 unsigned int argc, i, ret = 0, buffer = 0; 284 unsigned int argc, i, ret = 0; 285 size_t buffer = 0; 226 286 int c, opt_ind; 287 aoff64_t head = CAT_FULL_FILE, tail = CAT_FULL_FILE; 227 288 bool hex = false; 228 289 bool more = false; 290 bool tailFirst = false; 229 291 sysarg_t rows, cols; 230 292 int rc; … … 245 307 246 308 for (c = 0, optind = 0, opt_ind = 0; c != -1;) { 247 c = getopt_long(argc, argv, "xhvmH:t:b: ", long_options, &opt_ind);309 c = getopt_long(argc, argv, "xhvmH:t:b:s", long_options, &opt_ind); 248 310 switch (c) { 249 311 case 'h': … … 254 316 return CMD_SUCCESS; 255 317 case 'H': 256 printf("%s", cat_oops); 257 return CMD_FAILURE; 318 if (!optarg || str_uint64_t(optarg, NULL, 10, false, &head) != EOK ) { 319 puts("Invalid head size\n"); 320 return CMD_FAILURE; 321 } 322 break; 258 323 case 't': 259 printf("%s", cat_oops); 260 return CMD_FAILURE; 324 if (!optarg || str_uint64_t(optarg, NULL, 10, false, &tail) != EOK ) { 325 puts("Invalid tail size\n"); 326 return CMD_FAILURE; 327 } 328 if (head == CAT_FULL_FILE) 329 tailFirst = true; 330 break; 261 331 case 'b': 262 printf("%s", cat_oops); 332 if (!optarg || str_size_t(optarg, NULL, 10, false, &buffer) != EOK ) { 333 puts("Invalid buffer size\n"); 334 return CMD_FAILURE; 335 } 263 336 break; 264 337 case 'm': … … 267 340 case 'x': 268 341 hex = true; 342 break; 343 case 's': 344 dash_represents_stdin = true; 269 345 break; 270 346 } … … 279 355 } 280 356 281 if (buffer < = 0)357 if (buffer < 4) 282 358 buffer = CAT_DEFAULT_BUFLEN; 283 359 … … 295 371 296 372 for (i = optind; argv[i] != NULL && !should_quit; i++) 297 ret += cat_file(argv[i], buffer, hex );373 ret += cat_file(argv[i], buffer, hex, head, tail, tailFirst); 298 374 299 375 if (ret)
Note:
See TracChangeset
for help on using the changeset viewer.