From 8fd4943b2721696f86783d22dd2e8d593a22a766 Mon Sep 17 00:00:00 2001
From: dzwdz
Date: Fri, 2 Jun 2023 15:25:11 +0200
Subject: libc: stub out sltar's requirements

---
 src/user/lib/include/ftw.h           |  6 ++++
 src/user/lib/include/grp.h           | 11 +++++++
 src/user/lib/include/pwd.h           | 14 +++++++++
 src/user/lib/include/string.h        |  3 ++
 src/user/lib/include/sys/param.h     |  2 ++
 src/user/lib/include/sys/stat.h      | 59 ++++++++++++++++++++++++++++++++++--
 src/user/lib/include/sys/sysmacros.h |  3 ++
 src/user/lib/include/sys/types.h     |  9 ++++++
 src/user/lib/include/time.h          |  5 +++
 src/user/lib/include/unistd.h        | 12 ++++++++
 src/user/lib/pwd.c                   | 23 ++++++++++++++
 src/user/lib/string/string.c         | 24 ++++++++++++---
 src/user/lib/unistd.c                | 29 ++++++++++++++++++
 13 files changed, 194 insertions(+), 6 deletions(-)
 create mode 100644 src/user/lib/include/ftw.h
 create mode 100644 src/user/lib/include/grp.h
 create mode 100644 src/user/lib/include/sys/param.h
 create mode 100644 src/user/lib/include/sys/sysmacros.h
 create mode 100644 src/user/lib/pwd.c

(limited to 'src')

diff --git a/src/user/lib/include/ftw.h b/src/user/lib/include/ftw.h
new file mode 100644
index 0000000..6dc8132
--- /dev/null
+++ b/src/user/lib/include/ftw.h
@@ -0,0 +1,6 @@
+#pragma once
+#include <sys/stat.h>
+
+int ftw(const char *dirpath,
+		int (*fn)(const char *fpath, const struct stat *sb, int typeflag),
+		int nopenfd);
diff --git a/src/user/lib/include/grp.h b/src/user/lib/include/grp.h
new file mode 100644
index 0000000..e7b99c9
--- /dev/null
+++ b/src/user/lib/include/grp.h
@@ -0,0 +1,11 @@
+#pragma once
+#include <sys/types.h>
+
+struct group {
+	char *gr_name;
+	char *gr_passwd;
+	gid_t gr_gid;
+	char **gr_mem;
+};
+
+struct group *getgrgid(gid_t gid);
diff --git a/src/user/lib/include/pwd.h b/src/user/lib/include/pwd.h
index e69de29..6721ca2 100644
--- a/src/user/lib/include/pwd.h
+++ b/src/user/lib/include/pwd.h
@@ -0,0 +1,14 @@
+#pragma once
+#include <sys/types.h>
+
+struct passwd {
+	char *pw_name;
+	char *pw_passwd;
+	uid_t pw_uid;
+	gid_t pw_gid;
+	char *pw_gecos;
+	char *pw_dir;
+	char *pw_shell;
+};
+
+struct passwd *getpwuid(uid_t uid);
diff --git a/src/user/lib/include/string.h b/src/user/lib/include/string.h
index 38fb0d2..7a5400c 100644
--- a/src/user/lib/include/string.h
+++ b/src/user/lib/include/string.h
@@ -1,7 +1,10 @@
 #pragma once
 #include <shared/mem.h>
 
+// TODO move strto* to stdlib.h
 long strtol(const char *restrict s, char **restrict end, int base);
+unsigned long strtoul(const char *restrict s, char **restrict end, int base);
+unsigned long long strtoull(const char *restrict s, char **restrict end, int base);
 double strtod(const char *restrict s, char **restrict end);
 char *strchr(const char *s, int c);
 char *strrchr(const char *s, int c);
diff --git a/src/user/lib/include/sys/param.h b/src/user/lib/include/sys/param.h
new file mode 100644
index 0000000..e6c9d6f
--- /dev/null
+++ b/src/user/lib/include/sys/param.h
@@ -0,0 +1,2 @@
+#define MIN(a, b) ((a)<(b) ? (a):(b))
+#define MAX(a, b) ((a)<(b) ? (b):(a))
diff --git a/src/user/lib/include/sys/stat.h b/src/user/lib/include/sys/stat.h
index 5776f1e..9b9523c 100644
--- a/src/user/lib/include/sys/stat.h
+++ b/src/user/lib/include/sys/stat.h
@@ -1,14 +1,69 @@
 #pragma once
+#include <sys/stat.h>
 #include <sys/types.h>
+#include <time.h> // struct timespec
 #include <errno.h> // only for ENOSYS
 
-#define S_ISFIFO(x) 0
+struct stat {
+	dev_t st_dev;
+	ino_t st_ino;
+	mode_t st_mode;
+	nlink_t st_nlink;
+	uid_t st_uid;
+	gid_t st_gid;
+	dev_t st_rdev;
+	off_t st_size;
+	blksize_t st_blksize;
+	blkcnt_t st_blocks;
+
+	struct timespec st_atim;
+	struct timespec st_mtim;
+	struct timespec st_ctim;
+
+#define st_atime st_atim.tv_sec
+#define st_mtime st_mtim.tv_sec
+#define st_ctime st_ctim.tv_sec
+};
+
+#define S_IFMT  0170000
+#define S_IFSOCK 0140000
+#define S_IFLNK 0120000
+#define S_IFREG 0100000
+#define S_IFBLK 0060000
+#define S_IFDIR 0040000
+#define S_IFCHR 0020000
+#define S_IFIFO 0010000
+
+/* inode(7) */
+#define S_ISREG(m) ((m & S_IFMT) == S_IFREG)
+#define S_ISDIR(m) ((m & S_IFMT) == S_IFDIR)
+#define S_ISCHR(m) ((m & S_IFMT) == S_IFCHR)
+#define S_ISBLK(m) ((m & S_IFMT) == S_IFBLK)
+#define S_ISFIFO(m) ((m & S_IFMT) == S_IFIFO)
+#define S_ISLNK(m) ((m & S_IFMT) == S_IFLNK)
+#define S_ISSOCK(m) ((m & S_IFMT) == S_IFSOCK)
 
-struct stat {};
 static inline int fstat(int fd, struct stat *sb) {
 	(void)fd; (void)sb;
 	errno = ENOSYS;
 	return -1;
 }
 
+static inline int lstat(const char *restrict path, struct stat *restrict sb) {
+	(void)path; (void)sb;
+	errno = ENOSYS;
+	return -1;
+}
+
 int mkdir(const char *path, mode_t mode);
+static inline int chmod(const char *path, mode_t mode) {
+	(void)path; (void)mode;
+	errno = ENOSYS;
+	return -1;
+}
+
+static inline int mknod(const char *path, mode_t mode, dev_t dev) {
+	(void)path; (void)mode; (void)dev;
+	errno = ENOSYS;
+	return -1;
+}
diff --git a/src/user/lib/include/sys/sysmacros.h b/src/user/lib/include/sys/sysmacros.h
new file mode 100644
index 0000000..30e0efd
--- /dev/null
+++ b/src/user/lib/include/sys/sysmacros.h
@@ -0,0 +1,3 @@
+#define makedev(maj, min) 0
+#define major(x) 0
+#define minor(x) 0
diff --git a/src/user/lib/include/sys/types.h b/src/user/lib/include/sys/types.h
index 9f6f8f8..3b04988 100644
--- a/src/user/lib/include/sys/types.h
+++ b/src/user/lib/include/sys/types.h
@@ -6,3 +6,12 @@ typedef long long off_t;
 typedef int64_t time_t;
 typedef uint64_t clock_t;
 typedef int mode_t;
+
+typedef int dev_t;
+typedef int ino_t;
+typedef int mode_t;
+typedef int nlink_t;
+typedef int uid_t;
+typedef int gid_t;
+typedef int blksize_t;
+typedef int blkcnt_t;
diff --git a/src/user/lib/include/time.h b/src/user/lib/include/time.h
index 067c35f..5d03664 100644
--- a/src/user/lib/include/time.h
+++ b/src/user/lib/include/time.h
@@ -15,6 +15,11 @@ struct tm {
 	int tm_isdst;  /* Daylight Savings flag. */
 };
 
+struct timespec {
+	time_t tv_sec;
+	long long tv_nsec;
+};
+
 time_t time(time_t *tloc);
 clock_t clock(void);
 
diff --git a/src/user/lib/include/unistd.h b/src/user/lib/include/unistd.h
index a1c18e8..8c0eab0 100644
--- a/src/user/lib/include/unistd.h
+++ b/src/user/lib/include/unistd.h
@@ -1,18 +1,30 @@
 #pragma once
 #include <camellia/types.h> // TODO only needed because of hid_t
+#include <sys/types.h>
 #include <getopt.h>
 
+// TODO custom stdint.h, ssize_t doesn't belong here
+typedef long long ssize_t;
+
 int fork(void);
 int close(hid_t h);
 _Noreturn void _exit(int);
 
+ssize_t readlink(const char *restrict path, char *restrict buf, size_t bufsize);
+int link(const char *path1, const char *path2);
 int unlink(const char *path);
+int symlink(const char *path1, const char *path2);
 int isatty(int fd);
 
 int execv(const char *path, char *const argv[]);
 
 int chdir(const char *path);
 char *getcwd(char *buf, size_t size);
+
+uid_t getuid(void);
+int chown(const char *path, uid_t owner, gid_t group);
+
+
 /* Converts a relative path to an absolute one, simplifying it if possible.
  * If in == NULL - return the length of cwd. Doesn't include the trailing slash,
  *                 except for the root dir. Includes the null byte.
diff --git a/src/user/lib/pwd.c b/src/user/lib/pwd.c
new file mode 100644
index 0000000..d7bf2af
--- /dev/null
+++ b/src/user/lib/pwd.c
@@ -0,0 +1,23 @@
+#include <grp.h>
+#include <pwd.h>
+#include <string.h>
+
+struct passwd *
+getpwuid(uid_t uid)
+{
+	static struct passwd p;
+	memset(&p, 0, sizeof p);
+	p.pw_name = "unnamed";
+	p.pw_uid = uid;
+	return &p;
+}
+
+struct group *
+getgrgid(gid_t gid)
+{
+	static struct group g;
+	memset(&g, 0, sizeof g);
+	g.gr_name = "unnamed";
+	g.gr_gid = gid;
+	return &g;
+}
diff --git a/src/user/lib/string/string.c b/src/user/lib/string/string.c
index 8fdc7c7..7058573 100644
--- a/src/user/lib/string/string.c
+++ b/src/user/lib/string/string.c
@@ -3,17 +3,19 @@
 #include <string.h>
 #include <strings.h>
 
-long strtol(const char *restrict s, char **restrict end, int base) {
+static unsigned long long
+strton(const char *restrict s, char **restrict end, int base, int *sign)
+{
 	long res = 0;
-	int sign = 1;
 
 	while (isspace(*s)) s++;
 
+	if (sign) *sign = 1;
 	if (*s == '+') {
 		s++;
 	} else if (*s == '-') {
 		s++;
-		sign = -1;
+		if (sign) *sign = -1;
 	}
 
 	if (base == 0) {
@@ -45,7 +47,21 @@ long strtol(const char *restrict s, char **restrict end, int base) {
 		s++;
 	}
 	if (end) *end = (void*)s;
-	return res * sign;
+	return res;
+}
+
+long strtol(const char *restrict s, char **restrict end, int base) {
+	int sign;
+	long n = strton(s, end, base, &sign);
+	return n * sign;
+}
+
+unsigned long strtoul(const char *restrict s, char **restrict end, int base) {
+	return strton(s, end, base, NULL);
+}
+
+unsigned long long strtoull(const char *restrict s, char **restrict end, int base) {
+	return strton(s, end, base, NULL);
 }
 
 #include <bits/panic.h>
diff --git a/src/user/lib/unistd.c b/src/user/lib/unistd.c
index f81e7d8..4835238 100644
--- a/src/user/lib/unistd.c
+++ b/src/user/lib/unistd.c
@@ -23,6 +23,18 @@ _Noreturn void exit(int c) {
 }
 _Noreturn void _exit(int c) { exit(c); };
 
+ssize_t readlink(const char *restrict path, char *restrict buf, size_t bufsize) {
+	(void)path; (void)buf; (void)bufsize;
+	errno = ENOSYS;
+	return -1;
+}
+
+int link(const char *path1, const char *path2) {
+	(void)path1; (void)path2;
+	errno = ENOSYS;
+	return -1;
+}
+
 int unlink(const char *path) {
 	hid_t h = camellia_open(path, OPEN_WRITE);
 	if (h < 0) return errno = -h, -1;
@@ -31,6 +43,12 @@ int unlink(const char *path) {
 	return 0;
 }
 
+int symlink(const char *path1, const char *path2) {
+	(void)path1; (void)path2;
+	errno = ENOSYS;
+	return -1;
+}
+
 // TODO isatty
 int isatty(int fd) {
 	return fd <= 2 ? 1 : 0;
@@ -125,6 +143,17 @@ char *getcwd(char *buf, size_t capacity) {
 	return buf;
 }
 
+uid_t getuid(void) {
+	return 42;
+}
+
+int chown(const char *path, uid_t owner, gid_t group) {
+	(void)path; (void)owner; (void)group;
+	errno = ENOSYS;
+	return -1;
+}
+
+
 size_t absolutepath(char *out, const char *in, size_t size) {
 	const char *realcwd = getrealcwd();
 	size_t len, pos = 0;
-- 
cgit v1.2.3