Commit dee81e988674 ("fixdep: faster CONFIG_ search") changed how to read files in which CONFIG options are searched. It used malloc() and read() instead of mmap() because it needed to zero-terminate the buffer in order to use strstr(). print_deps() was left untouched since there was no reason to change it. Now, I have two motivations to change it in the same way. - do_config_file() and print_deps() do quite similar things; they open a file, load it onto memory, and pass it to a parser function. If we use malloc() and read() for print_deps() too, we can factor out the common code. (I will do this in the next commit.) - parse_dep_file() copies each token to a temporary buffer because it needs to zero-terminate it to be passed to printf(). It is not possible to modify the buffer directly because it is mmap'ed with O_RDONLY. If we load the file content into a malloc'ed buffer, we can insert '\0' after each token, and save memcpy(). (I will do this in the commit after next.)
Showing the changes to scripts/basic (1 of 1 file). Show all
Unified · Split
| @@ -104,7 +104,6 @@ · 103 unmodified lines | ||
| 104 | 104 | |
| 105 | 105 | #include <sys/types.h> |
| 106 | 106 | #include <sys/stat.h> |
| 107 | −#include <sys/mman.h> | |
| 108 | 107 | #include <unistd.h> |
| 109 | 108 | #include <fcntl.h> |
| 110 | 109 | #include <string.h> |
| @@ -308,24 +307,27 @@ static void do_config_file(const char *filename) · 197 unmodified lines | ||
| 308 | 307 | * assignments are parsed not only by make, but also by the rather simple |
| 309 | 308 | * parser in scripts/mod/sumversion.c. |
| 310 | 309 | */ |
| 311 | −static void parse_dep_file(void *map, size_t len) | |
| 310 | +static void parse_dep_file(char *m) | |
| 312 | 311 | { |
| 313 | − char *m = map; | |
| 314 | − char *end = m + len; | |
| 315 | 312 | char *p; |
| 316 | 313 | char s[PATH_MAX]; |
| 317 | − int is_target; | |
| 314 | + int is_last, is_target; | |
| 318 | 315 | int saw_any_target = 0; |
| 319 | 316 | int is_first_dep = 0; |
| 320 | 317 | |
| 321 | − while (m < end) { | |
| 318 | + while (1) { | |
| 322 | 319 | /* Skip any "white space" */ |
| 323 | − while (m < end && (*m == ' ' || *m == '\\' || *m == '\n')) | |
| 320 | + while (*m == ' ' || *m == '\\' || *m == '\n') | |
| 324 | 321 | m++; |
| 322 | + | |
| 323 | + if (!*m) | |
| 324 | + break; | |
| 325 | + | |
| 325 | 326 | /* Find next "white space" */ |
| 326 | 327 | p = m; |
| 327 | − while (p < end && *p != ' ' && *p != '\\' && *p != '\n') | |
| 328 | + while (*p && *p != ' ' && *p != '\\' && *p != '\n') | |
| 328 | 329 | p++; |
| 330 | + is_last = (*p == '\0'); | |
| 329 | 331 | /* Is the token we found a target name? */ |
| 330 | 332 | is_target = (*(p-1) == ':'); |
| 331 | 333 | /* Don't write any target names into the dependency file */ |
| @@ -373,6 +375,10 @@ static void parse_dep_file(void *map, size_t len) · 41 unmodified lines | ||
| 373 | 375 | do_config_file(s); |
| 374 | 376 | } |
| 375 | 377 | } |
| 378 | + | |
| 379 | + if (is_last) | |
| 380 | + break; | |
| 381 | + | |
| 376 | 382 | /* |
| 377 | 383 | * Start searching for next token immediately after the first |
| 378 | 384 | * "whitespace" character that follows this token. |
| @@ -391,40 +397,42 @@ static void parse_dep_file(void *map, size_t len) · 12 unmodified lines | ||
| 391 | 397 | printf("$(deps_%s):\n", target); |
| 392 | 398 | } |
| 393 | 399 | |
| 394 | −static void print_deps(void) | |
| 400 | +static void print_deps(const char *filename) | |
| 395 | 401 | { |
| 396 | 402 | struct stat st; |
| 397 | 403 | int fd; |
| 398 | − void *map; | |
| 404 | + char *buf; | |
| 399 | 405 | |
| 400 | − fd = open(depfile, O_RDONLY); | |
| 406 | + fd = open(filename, O_RDONLY); | |
| 401 | 407 | if (fd < 0) { |
| 402 | 408 | fprintf(stderr, "fixdep: error opening depfile: "); |
| 403 | − perror(depfile); | |
| 409 | + perror(filename); | |
| 404 | 410 | exit(2); |
| 405 | 411 | } |
| 406 | 412 | if (fstat(fd, &st) < 0) { |
| 407 | 413 | fprintf(stderr, "fixdep: error fstat'ing depfile: "); |
| 408 | − perror(depfile); | |
| 414 | + perror(filename); | |
| 409 | 415 | exit(2); |
| 410 | 416 | } |
| 411 | 417 | if (st.st_size == 0) { |
| 412 | − fprintf(stderr,"fixdep: %s is empty\n",depfile); | |
| 413 | 418 | close(fd); |
| 414 | 419 | return; |
| 415 | 420 | } |
| 416 | − map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); | |
| 417 | − if ((long) map == -1) { | |
| 418 | − perror("fixdep: mmap"); | |
| 419 | − close(fd); | |
| 420 | − return; | |
| 421 | + buf = malloc(st.st_size + 1); | |
| 422 | + if (!buf) { | |
| 423 | + perror("fixdep: malloc"); | |
| 424 | + exit(2); | |
| 421 | 425 | } |
| 426 | + if (read(fd, buf, st.st_size) != st.st_size) { | |
| 427 | + perror("fixdep: read"); | |
| 428 | + exit(2); | |
| 429 | + } | |
| 430 | + buf[st.st_size] = '\0'; | |
| 431 | + close(fd); | |
| 422 | 432 | |
| 423 | − parse_dep_file(map, st.st_size); | |
| 424 | − | |
| 425 | − munmap(map, st.st_size); | |
| 433 | + parse_dep_file(buf); | |
| 426 | 434 | |
| 427 | − close(fd); | |
| 435 | + free(buf); | |
| 428 | 436 | } |
| 429 | 437 | |
| 430 | 438 | int main(int argc, char *argv[]) |
| @@ -440,7 +448,7 @@ int main(int argc, char *argv[]) · 9 unmodified lines | ||
| 440 | 448 | cmdline = argv[3]; |
| 441 | 449 | |
| 442 | 450 | print_cmdline(); |
| 443 | − print_deps(); | |
| 451 | + print_deps(depfile); | |
| 444 | 452 | |
| 445 | 453 | return 0; |
| 446 | 454 | } |