Raymond Toy pushed to branch issue-130-file-author-in-c at cmucl / cmucl

Commits:

1 changed file:

Changes:

  • src/lisp/os-common.c
    ... ... @@ -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
     }