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

Commits:

1 changed file:

Changes:

  • src/lisp/os-common.c
    ... ... @@ -727,66 +727,42 @@ os_lstat(const char* path, u_int64_t *dev, u_int64_t *ino, unsigned int *mode, u
    727 727
     char *
    
    728 728
     os_file_author(const char *path)
    
    729 729
     {
    
    730
    -    int status;
    
    731
    -    struct stat statbuf;
    
    732
    -    char* author = NULL;
    
    733
    -    bool nomem = false;
    
    734
    -    size_t bufsize;
    
    735
    -    char* buf = NULL;
    
    736
    -    char* buf2 = NULL;
    
    730
    +    struct stat sb;
    
    731
    +    char initial[1024];
    
    732
    +    char *buffer, *obuffer;
    
    733
    +    size_t size;
    
    737 734
         struct passwd pwd;
    
    738
    -    struct passwd *result = NULL;
    
    739
    -    
    
    740
    -    status = stat(path, &statbuf);
    
    735
    +    struct passwd *ppwd;
    
    736
    +    char *result;
    
    741 737
     
    
    742
    -    if (status != 0) {
    
    738
    +    if (stat(path, &sb) != 0) {
    
    743 739
             return NULL;
    
    744 740
         }
    
    745
    -
    
    746
    -    bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
    
    747
    -
    
    748
    -    /*
    
    749
    -     * If sysconf fails, just use a small initial buffer size that we
    
    750
    -     * will keep growing up to some maximum size.
    
    751
    -     */
    
    752
    -    if (bufsize == -1) {
    
    753
    -        bufsize = 1024;
    
    754
    -    }
    
    755
    -    
    
    756
    -    while (1) {
    
    757
    -        buf2 = realloc(buf, 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;
    
    741
    +    result = NULL;
    
    742
    +    buffer = initial;
    
    743
    +    size = ARRAYSIZE(initial);
    
    744
    +    assert(sysconf(_SC_GETPW_R_SIZE_MAX) <= 16384));
    
    745
    +    while (size <= 16384) {
    
    746
    +        switch (getpwuid_r(sb.st_uid, &pwd, buffer, size, &ppwd)) {
    
    747
    +        case 0:
    
    748
    +            /* Success, though we might not have a matching entry */
    
    749
    +            result = (ppwd == NULL) ? NULL : strdup(pwd.pw_name);
    
    750
    +            goto exit;
    
    751
    +        case ERANGE:
    
    752
    +            /* Buffer is too small, double its size and try again */
    
    753
    +            size *= 2;
    
    754
    +            obuffer = (buffer == initial) ? NULL : buffer;
    
    755
    +            if ((buffer = realloc(obuffer, size)) == NULL) {
    
    756
    +                free(obuffer); 
    
    757
    +                goto exit;
    
    758
    +            }
    
    759
    +            continue;
    
    760
    +        default:
    
    761
    +            /* All other errors */
    
    762
    +            goto exit;
    
    778 763
             }
    
    779
    -
    
    780
    -        bufsize <<= 1;
    
    781 764
         }
    
    782
    -    
    
    783
    -    if (result) {
    
    784
    -        author = strdup(result->pw_name);
    
    785
    -    }
    
    786
    -
    
    787
    -    if (buf) {
    
    788
    -        free(buf);
    
    789
    -    }
    
    790
    -
    
    791
    -    return author;
    
    765
    +exit:
    
    766
    +    free(buffer);
    
    767
    +    return result;
    
    792 768
     }