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 | } |