diff options
author | dzwdz | 2024-05-05 14:58:44 +0200 |
---|---|---|
committer | dzwdz | 2024-05-05 14:58:58 +0200 |
commit | cb518ecd55cd7a45d0368fb9d68a1981c6c91adf (patch) | |
tree | c25ecffeeaf4f1f7d33b4ced91515d43a79c2dd5 | |
parent | 80839982e9983c6ccadbf57a44e60eeb0e535421 (diff) |
libc: implement asprintf
-rw-r--r-- | src/cmd/find.c | 26 | ||||
-rw-r--r-- | src/cmd/ps.c | 23 | ||||
-rw-r--r-- | src/libc/include/stdio.h | 2 | ||||
-rw-r--r-- | src/libc/stdio/asprintf.c | 24 |
4 files changed, 45 insertions, 30 deletions
diff --git a/src/cmd/find.c b/src/cmd/find.c index d473b82..8f0352c 100644 --- a/src/cmd/find.c +++ b/src/cmd/find.c @@ -1,4 +1,3 @@ -#include <camellia/path.h> #include <dirent.h> #include <err.h> #include <errno.h> @@ -6,7 +5,7 @@ #include <stdlib.h> #include <string.h> -void recurse(char *path) { +void recurse(const char *path) { DIR *d = opendir(path); if (!d) { warn("couldn't open %s", path); @@ -25,31 +24,22 @@ void recurse(char *path) { printf("%s%s\n", path, dent->d_name); /* if the string ends with '/' */ if (strchr(dent->d_name, '\0')[-1] == '/') { - // TODO no overflow check - char *pend = strchr(path, '\0'); - strcpy(pend, dent->d_name); - recurse(path); - *pend = '\0'; + char *next; + if (asprintf(&next, "%s%s", path, dent->d_name) >= 0) { + recurse(next); + free(next); + } } } closedir(d); } -void find(const char *path) { - // TODO bound checking - // TODO or just implement asprintf() - char *buf = malloc(PATH_MAX); - memcpy(buf, path, strlen(path)+1); - recurse(buf); - free(buf); -} - int main(int argc, char **argv) { if (argc < 2) { - find("/"); + recurse("/"); } else { for (int i = 1; i < argc; i++) - find(argv[i]); + recurse(argv[i]); } return 0; } diff --git a/src/cmd/ps.c b/src/cmd/ps.c index c855251..98aab8a 100644 --- a/src/cmd/ps.c +++ b/src/cmd/ps.c @@ -19,7 +19,6 @@ main(int argc, const char *argv[]) const char *path = argc >= 2 ? argv[1] : "/proc/"; if (argc > 2) usage(); - char *procbuf = malloc(4096); DIR *dir = opendir(path); if (!dir) { err(1, "couldn't open %s", path); @@ -28,27 +27,27 @@ main(int argc, const char *argv[]) struct dirent *de; while ((de = readdir(dir))) { const char *name = de->d_name; - if (isdigit(name[0])) { - FILE *g; - sprintf(procbuf, "%s%smem", path, name); - g = fopen(procbuf, "r"); + char psdata[128]; + char *s; + if (isdigit(name[0]) && asprintf(&s, "%s%smem", path, name) >= 0) { + FILE *g = fopen(s, "r"); + free(s); if (!g) { - warn("couldn't open \"%s\"", procbuf); - strcpy(procbuf, "(can't peek)"); + warn("couldn't open \"%s\"", s); + strcpy(psdata, "(can't peek)"); } else { fseek(g, (long)&_psdata_loc->desc, SEEK_SET); - if (fread(procbuf, 1, 128, g) <= 0) { - strcpy(procbuf, "(no psdata)"); + if (fread(psdata, 1, sizeof(psdata)-1, g) <= 0) { + strcpy(psdata, "(no psdata)"); } - procbuf[128] = '\0'; + psdata[sizeof(psdata)-1] = '\0'; fclose(g); } *strchr(name, '/') = '\0'; - printf("%s\t%s\n", name, procbuf); + printf("%s\t%s\n", name, psdata); } } - free(procbuf); closedir(dir); return 0; } diff --git a/src/libc/include/stdio.h b/src/libc/include/stdio.h index b582e8f..159bdca 100644 --- a/src/libc/include/stdio.h +++ b/src/libc/include/stdio.h @@ -28,10 +28,12 @@ int printf(const char *restrict fmt, ...); int fprintf(FILE *restrict f, const char *restrict fmt, ...); int sprintf(char *restrict s, const char *restrict fmt, ...); +int asprintf(char **restrict sp, const char *restrict fmt, ...); int snprintf(char *restrict str, size_t len, const char *restrict fmt, ...); int vprintf(const char *restrict fmt, va_list ap); int vsprintf(char *restrict s, const char *restrict fmt, va_list ap); +int vasprintf(char **restrict sp, const char *restrict fmt, va_list ap); int vfprintf(FILE *restrict f, const char *restrict fmt, va_list ap); int _klogf(const char *fmt, ...); // for kernel debugging only diff --git a/src/libc/stdio/asprintf.c b/src/libc/stdio/asprintf.c new file mode 100644 index 0000000..ee24e38 --- /dev/null +++ b/src/libc/stdio/asprintf.c @@ -0,0 +1,24 @@ +#include <shared/mem.h> +#include <shared/printf.h> +#include <stdio.h> +#include <stdlib.h> + +int asprintf(char **restrict sp, const char *restrict fmt, ...) { + int ret; + va_list argp; + va_start(argp, fmt); + ret = vasprintf(sp, fmt, argp); + va_end(argp); + return ret; +} +int vasprintf(char **restrict sp, const char *restrict fmt, va_list ap) { + va_list ap2; + va_copy(ap2, ap); + int ret = vsnprintf(NULL, 0, fmt, ap2); + va_end(ap2); + + if (ret < 0) return ret; + *sp = malloc(ret+1); + if (*sp == NULL) return -1; + return vsnprintf(*sp, ret+1, fmt, ap); +} |