[Git][cmucl/cmucl][issue-130-file-author-in-c] Use sysconf to get buffer size and add loop to increase size

Raymond Toy (@rtoy) gitlab at common-lisp.net
Mon Aug 29 19:05:45 UTC 2022



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
Use sysconf to get buffer size and add loop to increase size

Use sysconf to get the buffer size.  If it fails, use a default and
add a loop to keep trying with a larger buffer size (until some upper
limit is reached.)

- - - - -


1 changed file:

- src/lisp/os-common.c


Changes:

=====================================
src/lisp/os-common.c
=====================================
@@ -9,6 +9,7 @@
 #include <math.h>
 #include <netdb.h>
 #include <pwd.h>
+#include <stdbool.h>
 #include <stdio.h>
 #include <string.h>
 #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
 char *
 os_file_author(const char *path)
 {
-    int rc;
+    int status;
     struct stat statbuf;
-    char buf[16384];
     char* author = NULL;
+    bool nomem = false;
+    size_t bufsize;
+    char* buf = NULL;
+    char* buf2 = NULL;
     struct passwd pwd;
     struct passwd *result = NULL;
     
-    rc = stat(path, &statbuf);
+    status = stat(path, &statbuf);
 
-    if (rc != 0) {
+    if (status != 0) {
         return NULL;
     }
 
-    rc = getpwuid_r(statbuf.st_uid, &pwd, buf, sizeof(buf), &result);
+    bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
 
+    /*
+     * If sysconf fails, just use a small initial buffer size that we
+     * will keep growing up to some maximum size.
+     */
+    if (bufsize == -1) {
+        bufsize = 1024;
+    }
+    
+    while (1) {
+        buf2 = realloc(buf, bufsize);
+        fprintf(stderr, "buf2 = %p, size %zu\n", buf2, bufsize);
+        
+        if (buf2 == NULL) {
+            result = NULL;
+            nomem = true;
+            break;
+        }
+        
+        buf = buf2;
+        status = getpwuid_r(statbuf.st_uid, &pwd, buf, bufsize, &result);
+
+        if (status != 0) {
+            result = NULL;
+        }
+        if ((result != NULL) || (status != ERANGE)) {
+            break;
+        }
+        /* If bufsize exceeds some large size, give up. */
+        if (bufsize > 16384) {
+            nomem = true;
+            break;
+        }
+
+        bufsize <<= 1;
+    }
+    
     if (result) {
         author = malloc(strlen(result->pw_name + 1));
         if (author) {
@@ -747,5 +787,7 @@ os_file_author(const char *path)
         }
     }
 
+    free(buf);
+
     return author;
 }



View it on GitLab: https://gitlab.common-lisp.net/cmucl/cmucl/-/commit/fe9fa1dbfdc86cd86ae4f19f636c41cdad5f3197

-- 
View it on GitLab: https://gitlab.common-lisp.net/cmucl/cmucl/-/commit/fe9fa1dbfdc86cd86ae4f19f636c41cdad5f3197
You're receiving this email because of your account on gitlab.common-lisp.net.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.common-lisp.net/pipermail/cmucl-cvs/attachments/20220829/1fffa82c/attachment-0001.html>


More information about the cmucl-cvs mailing list