Kaynağa Gözat

feat(gblibc): asprintf and vasprintf

greatbridf 2 yıl önce
ebeveyn
işleme
b8bfecd56f
3 değiştirilmiş dosya ile 41 ekleme ve 2 silme
  1. 2 0
      gblibc/include/stdio.h
  2. 34 0
      gblibc/src/stdio.c
  3. 5 2
      user-space-program/init.c

+ 2 - 0
gblibc/include/stdio.h

@@ -37,6 +37,8 @@ char* gets(char* str);
 int vsnprintf(char* buf, size_t bufsize, const char* fmt, va_list args);
 int snprintf(char* buf, size_t bufsize, const char* fmt, ...);
 int sprintf(char* buf, const char* fmt, ...);
+int vasprintf(char** strp, const char* fmt, va_list args);
+int asprintf(char** strp, const char* fmt, ...);
 
 int vfprintf(FILE* stream, const char* fmt, va_list args);
 int fprintf(FILE* stream, const char* fmt, ...);

+ 34 - 0
gblibc/src/stdio.c

@@ -811,3 +811,37 @@ void clearerr(FILE* stream)
 {
     stream->flags &= ~FILE_ERROR;
 }
+
+int vasprintf(char** strp, const char* fmt, va_list args)
+{
+    // TODO: this is WAY TOO SLOWWWWWWWWW
+    int sz = 8, n;
+    char* buf = NULL;
+
+    do {
+        buf = malloc(sz *= 2);
+        if (!buf)
+            return -1;
+        
+        n = vsnprintf(buf, sz, fmt, args);
+        if (sz > n)
+            break;
+
+        free(buf);
+    } while (1);
+    
+    *strp = buf;
+    return n;
+}
+
+int asprintf(char** strp, const char* fmt, ...)
+{
+    va_list lst;
+    va_start(lst, fmt);
+
+    int ret = vasprintf(strp, fmt, lst);
+
+    va_end(lst);
+
+    return ret;
+}

+ 5 - 2
user-space-program/init.c

@@ -1,4 +1,6 @@
+#include <assert.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 #include <fcntl.h>
@@ -52,11 +54,12 @@ _run_sh:;
     }
 
     int ret, pid;
-    char buf[512] = {};
     for (;;) {
         pid = wait(&ret);
-        snprintf(buf, sizeof(buf), "[init] pid%d has exited with code %d\n", pid, ret);
+        char* buf = NULL;
+        assert(asprintf(&buf, "[init] pid%d has exited with code %d\n", pid, ret) >= 0);
         print(buf);
+        free(buf);
         // sh
         if (pid == sh_pid)
             goto _run_sh;