Raymond Toy pushed to branch issue-130-file-author-in-c at cmucl / cmucl
Commits:
-
fe9fa1db
by Raymond Toy at 2022-08-29T12:05:30-07:00
1 changed file:
Changes:
| ... | ... | @@ -9,6 +9,7 @@ |
| 9 | 9 | #include <math.h>
|
| 10 | 10 | #include <netdb.h>
|
| 11 | 11 | #include <pwd.h>
|
| 12 | +#include <stdbool.h>
|
|
| 12 | 13 | #include <stdio.h>
|
| 13 | 14 | #include <string.h>
|
| 14 | 15 | #include <sys/stat.h>
|
| ... | ... | @@ -725,21 +726,60 @@ os_lstat(const char* path, u_int64_t *dev, u_int64_t *ino, unsigned int *mode, u |
| 725 | 726 | char *
|
| 726 | 727 | os_file_author(const char *path)
|
| 727 | 728 | {
|
| 728 | - int rc;
|
|
| 729 | + int status;
|
|
| 729 | 730 | struct stat statbuf;
|
| 730 | - char buf[16384];
|
|
| 731 | 731 | char* author = NULL;
|
| 732 | + bool nomem = false;
|
|
| 733 | + size_t bufsize;
|
|
| 734 | + char* buf = NULL;
|
|
| 735 | + char* buf2 = NULL;
|
|
| 732 | 736 | struct passwd pwd;
|
| 733 | 737 | struct passwd *result = NULL;
|
| 734 | 738 |
|
| 735 | - rc = stat(path, &statbuf);
|
|
| 739 | + status = stat(path, &statbuf);
|
|
| 736 | 740 | |
| 737 | - if (rc != 0) {
|
|
| 741 | + if (status != 0) {
|
|
| 738 | 742 | return NULL;
|
| 739 | 743 | }
|
| 740 | 744 | |
| 741 | - rc = getpwuid_r(statbuf.st_uid, &pwd, buf, sizeof(buf), &result);
|
|
| 745 | + bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
|
|
| 742 | 746 | |
| 747 | + /*
|
|
| 748 | + * If sysconf fails, just use a small initial buffer size that we
|
|
| 749 | + * will keep growing up to some maximum size.
|
|
| 750 | + */
|
|
| 751 | + if (bufsize == -1) {
|
|
| 752 | + bufsize = 1024;
|
|
| 753 | + }
|
|
| 754 | +
|
|
| 755 | + while (1) {
|
|
| 756 | + buf2 = realloc(buf, bufsize);
|
|
| 757 | + fprintf(stderr, "buf2 = %p, size %zu\n", buf2, bufsize);
|
|
| 758 | +
|
|
| 759 | + if (buf2 == NULL) {
|
|
| 760 | + result = NULL;
|
|
| 761 | + nomem = true;
|
|
| 762 | + break;
|
|
| 763 | + }
|
|
| 764 | +
|
|
| 765 | + buf = buf2;
|
|
| 766 | + status = getpwuid_r(statbuf.st_uid, &pwd, buf, bufsize, &result);
|
|
| 767 | + |
|
| 768 | + if (status != 0) {
|
|
| 769 | + result = NULL;
|
|
| 770 | + }
|
|
| 771 | + if ((result != NULL) || (status != ERANGE)) {
|
|
| 772 | + break;
|
|
| 773 | + }
|
|
| 774 | + /* If bufsize exceeds some large size, give up. */
|
|
| 775 | + if (bufsize > 16384) {
|
|
| 776 | + nomem = true;
|
|
| 777 | + break;
|
|
| 778 | + }
|
|
| 779 | + |
|
| 780 | + bufsize <<= 1;
|
|
| 781 | + }
|
|
| 782 | +
|
|
| 743 | 783 | if (result) {
|
| 744 | 784 | author = malloc(strlen(result->pw_name + 1));
|
| 745 | 785 | if (author) {
|
| ... | ... | @@ -747,5 +787,7 @@ os_file_author(const char *path) |
| 747 | 787 | }
|
| 748 | 788 | }
|
| 749 | 789 | |
| 790 | + free(buf);
|
|
| 791 | + |
|
| 750 | 792 | return author;
|
| 751 | 793 | } |