summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordzwdz2024-05-05 14:58:44 +0200
committerdzwdz2024-05-05 14:58:58 +0200
commitcb518ecd55cd7a45d0368fb9d68a1981c6c91adf (patch)
treec25ecffeeaf4f1f7d33b4ced91515d43a79c2dd5
parent80839982e9983c6ccadbf57a44e60eeb0e535421 (diff)
libc: implement asprintf
-rw-r--r--src/cmd/find.c26
-rw-r--r--src/cmd/ps.c23
-rw-r--r--src/libc/include/stdio.h2
-rw-r--r--src/libc/stdio/asprintf.c24
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);
+}