diff options
author | dzwdz | 2023-08-14 18:51:07 +0200 |
---|---|---|
committer | dzwdz | 2023-08-14 18:51:07 +0200 |
commit | 642b5fb0007b64c77d186fcb018d571152ee1d47 (patch) | |
tree | 1c466461f3602d306be309a053edae558ef2568e /src/shared | |
parent | 8050069c57b729c18c19b1a03ab6e4bf63b4735e (diff) |
reorganization: first steps
Diffstat (limited to 'src/shared')
-rw-r--r-- | src/shared/fsutil.c | 51 | ||||
-rw-r--r-- | src/shared/include/assert.h | 7 | ||||
-rw-r--r-- | src/shared/include/camellia/errno.h | 28 | ||||
-rw-r--r-- | src/shared/include/camellia/execbuf.h | 9 | ||||
-rw-r--r-- | src/shared/include/camellia/flags.h | 35 | ||||
-rw-r--r-- | src/shared/include/camellia/fsutil.h | 12 | ||||
-rw-r--r-- | src/shared/include/camellia/path.h | 17 | ||||
-rw-r--r-- | src/shared/include/camellia/syscalls.h | 96 | ||||
-rw-r--r-- | src/shared/include/camellia/types.h | 41 | ||||
-rw-r--r-- | src/shared/include/shared/mem.h | 18 | ||||
-rw-r--r-- | src/shared/include/shared/printf.h | 6 | ||||
-rw-r--r-- | src/shared/include/shared/ring.h | 23 | ||||
-rw-r--r-- | src/shared/mem.c | 82 | ||||
-rw-r--r-- | src/shared/path.c | 53 | ||||
-rw-r--r-- | src/shared/printf.c | 268 | ||||
-rw-r--r-- | src/shared/ring.c | 60 |
16 files changed, 0 insertions, 806 deletions
diff --git a/src/shared/fsutil.c b/src/shared/fsutil.c deleted file mode 100644 index 05ca44a..0000000 --- a/src/shared/fsutil.c +++ /dev/null @@ -1,51 +0,0 @@ -#include <assert.h> -#include <camellia/fsutil.h> -#include <limits.h> - -void fs_normslice(long *restrict offset, size_t *restrict length, size_t max, bool expand) -{ - assert(max <= (size_t)LONG_MAX); - - if (*offset < 0) { - /* Negative offsets are relative to EOF + 1. - * Thus: - * write(-1) writes right after the file ends; atomic append - * write(-n) writes, overriding the last (n-1) bytes - * read(-n) reads the last (n-1) bytes - */ - *offset += max + 1; - if (*offset < 0) { - /* cursor went before the file, EOF */ - *length = 0; - *offset = max; - goto end; - } - } - - if (expand) { - /* This is a write() to a file with a dynamic size. - * We don't care if it goes past the current size, because the - * driver can handle expanding it. */ - } else { - /* This operation can't extend the file, it's either: - * - any read() - * - a write() to a file with a static size (e.g. a framebuffer) - * *offset and *length describe a slice of a buffer with length max, - * so their sum must not overflow it. */ - if ((size_t)*offset <= max) { - size_t maxlen = max - (size_t)*offset; - if (*length > maxlen) - *length = maxlen; - } else { - /* regular EOF */ - *length = 0; - *offset = max; - goto end; - } - } - -end: - assert(0 <= *offset); - if (!expand) - assert(*offset + *length <= max); -} diff --git a/src/shared/include/assert.h b/src/shared/include/assert.h deleted file mode 100644 index 7520aa9..0000000 --- a/src/shared/include/assert.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifdef NDEBUG -#define assert(stmt) do {} while (0) -#else -#define assert(stmt) do { if (!(stmt)) __badassert(__func__, __FILE__, __LINE__); } while (0) -#endif - -_Noreturn void __badassert(const char *func, const char *file, int line); diff --git a/src/shared/include/camellia/errno.h b/src/shared/include/camellia/errno.h deleted file mode 100644 index 1177f54..0000000 --- a/src/shared/include/camellia/errno.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once -/* the comments are directly pasted into user visible strings. - * keep them short, don't include " */ - -#define EGENERIC 1 /* unknown error */ -#define EFAULT 2 -#define EBADF 3 /* bad file descriptor */ -#define EINVAL 4 -#define ENOSYS 5 /* unsupported */ -#define ERANGE 6 -#define ENOMEM 7 -#define ENOENT 8 -#define ENOTEMPTY 9 -#define EACCES 10 -#define EMFILE 11 /* all file descriptors taken */ -#define ECONNRESET 12 -#define EPIPE 13 -#define ECHILD 14 - -#define EISDIR 200 -#define ENAMETOOLONG 201 -#define ENOTDIR 202 -#define ELOOP 203 -#define ENOEXEC 204 -#define EINTR 205 -#define EWOULDBLOCK 206 -#define EEXIST 207 -#define EAGAIN 208 diff --git a/src/shared/include/camellia/execbuf.h b/src/shared/include/camellia/execbuf.h deleted file mode 100644 index de7ae3b..0000000 --- a/src/shared/include/camellia/execbuf.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -/* the instruction format is bound to change, atm it's extremely inefficient */ - -#define EXECBUF_MAX_LEN 4096 - -/* takes 6 arguments */ -#define EXECBUF_SYSCALL 0xF0000001 -/* takes 1 argument, changes %rip */ -#define EXECBUF_JMP 0xF0000002 diff --git a/src/shared/include/camellia/flags.h b/src/shared/include/camellia/flags.h deleted file mode 100644 index f4c54fe..0000000 --- a/src/shared/include/camellia/flags.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once - -#define MEMFLAG_PRESENT 1 -#define MEMFLAG_FINDFREE 2 - -#define FORK_NOREAP 1 -#define FORK_NEWFS 2 -#define FORK_SHAREMEM 4 -#define FORK_SHAREHANDLE 8 - -#define WRITE_TRUNCATE 1 - -#define FSR_DELEGATE 1 - -#define DUP_SEARCH 1 - -#define OPEN_READ 1 -#define OPEN_WRITE 2 -#define OPEN_RW 3 -/* not setting OPEN_READ nor OPEN_WRITE works as if OPEN_READ was set, but it also checks the execute bit. - * same as in plan9. */ -#define OPEN_EXEC 0 - -#define OPEN_READABLE(flags) ((flags & 3) != OPEN_WRITE) -#define OPEN_WRITEABLE(flags) (flags & OPEN_WRITE) - -/* Requires OPEN_WRITE to be set, enforced by the kernel. - * The idea is that if all flags which allow modifying the filesystem state require - * OPEN_WRITE to be set, filesystem handlers could just check for the OPEN_WRITE flag. */ -#define OPEN_CREATE 4 - - -/* special handles */ -#define HANDLE_NULLFS -2 -#define HANDLE_PROCFS -3 diff --git a/src/shared/include/camellia/fsutil.h b/src/shared/include/camellia/fsutil.h deleted file mode 100644 index 8b8c4fc..0000000 --- a/src/shared/include/camellia/fsutil.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -#include <stdbool.h> -#include <stddef.h> - -/** Normalizes the offset and length passed to a fs into safe values. - * - * @param expand Can this operation expand the target file? - * true if writing to a file with an adjustable size - * false if reading any sort of file - * or writing to a file with static size - */ -void fs_normslice(long *restrict offset, size_t *restrict length, size_t max, bool expand); diff --git a/src/shared/include/camellia/path.h b/src/shared/include/camellia/path.h deleted file mode 100644 index b268595..0000000 --- a/src/shared/include/camellia/path.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once -#include <stddef.h> - -#define PATH_MAX 512 - -/** Reduce a path to its simplest form. - * Kinds of invalid paths: - * - relative - "" "a" "./a" - * - going behind the root directory - "/../" - * - * @return On success, length of the string in *out, <= len. 0 if the path was invalid. - * - * returns an unsigned type because: - * 1. valid paths always return at least 1, for the initial slash - * 2. it makes it easier to assign the result to an unsigned variable and check for error - */ -size_t path_simplify(const char *in, char *out, size_t len); diff --git a/src/shared/include/camellia/syscalls.h b/src/shared/include/camellia/syscalls.h deleted file mode 100644 index 9a8fa94..0000000 --- a/src/shared/include/camellia/syscalls.h +++ /dev/null @@ -1,96 +0,0 @@ -#pragma once - -#define _SYS_EXIT 0 -#define _SYS_AWAIT 1 -#define _SYS_FORK 2 -#define _SYS_OPEN 3 -#define _SYS_MOUNT 4 -#define _SYS_DUP 5 -#define _SYS_READ 6 -#define _SYS_WRITE 7 -#define _SYS_GETSIZE 8 -#define _SYS_REMOVE 9 -#define _SYS_CLOSE 10 -#define _SYS_FS_WAIT 11 -#define _SYS_FS_RESPOND 12 -#define _SYS_MEMFLAG 13 -#define _SYS_PIPE 14 -#define _SYS_SLEEP 15 -#define _SYS_FILICIDE 16 -#define _SYS_INTR 17 -#define _SYS_INTR_SET 18 -#define _SYS_GETPID 19 -#define _SYS_GETPPID 20 -#define _SYS_WAIT2 21 - -#define _SYS_EXECBUF 100 -#define _SYS_DEBUG_KLOG 101 - -#ifndef ASM_FILE -#include <camellia/types.h> -#include <stddef.h> - -long _syscall(long, long, long, long, long, long); - -/** Kills the current process. - */ -_Noreturn void _sys_exit(long ret); - -/** Waits for a child to exit. - * @return the value the child passed to exit() - */ -long _sys_await(void); - -/** Creates a copy of the current process, and executes it. - * All user memory pages get copied too. - * - * @param flags FORK_NOREAP, FORK_NEWFS - * @param fs_front requires FORK_NEWFS. the front handle to the new fs is put there - * - * @return 0 in the child, the CID in the parent. - */ -long _sys_fork(int flags, hid_t __user *fs_front); - -hid_t _sys_open(const char __user *path, long len, int flags); -long _sys_mount(hid_t h, const char __user *path, long len); -hid_t _sys_dup(hid_t from, hid_t to, int flags); - -long _sys_read(hid_t h, void __user *buf, size_t len, long offset); -long _sys_write(hid_t h, const void __user *buf, size_t len, long offset, int flags); -long _sys_getsize(hid_t h); -long _sys_remove(hid_t h); -long _sys_close(hid_t h); - -hid_t _sys_fs_wait(char __user *buf, long max_len, struct ufs_request __user *res); -long _sys_fs_respond(hid_t hid, const void __user *buf, long ret, int flags); - -/** Modifies the virtual address space. - * - * If the MEMFLAG_PRESENT flag is present - mark the memory region as allocated. - * Otherwise, free it. - * - * MEMFLAG_FINDFREE tries to find the first free region of length `len`. - * - * @return address of the first affected page (usually == addr) - */ -void __user *_sys_memflag(void __user *addr, size_t len, int flags); -long _sys_pipe(hid_t __user user_ends[2], int flags); - -void _sys_sleep(long ms); - -void _sys_filicide(void); -void _sys_intr(void); -void _sys_intr_set(void __user *ip); - -uint32_t _sys_getpid(void); -uint32_t _sys_getppid(void); - -// TODO deprecate await -int _sys_wait2(int pid, int flags, struct sys_wait2 __user *out); - -/* see shared/execbuf.h */ -long _sys_execbuf(void __user *buf, size_t len); - -void _sys_debug_klog(const void __user *buf, size_t len); - -#endif diff --git a/src/shared/include/camellia/types.h b/src/shared/include/camellia/types.h deleted file mode 100644 index 65200d7..0000000 --- a/src/shared/include/camellia/types.h +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once -#include <stddef.h> -#include <stdint.h> - -#ifdef __CHECKER__ -# define __user __attribute__((noderef, address_space(__user))) -# define __force __attribute__((force)) -#else -# define __user -# define __force -#endif - -typedef void __user * userptr_t; -typedef int hid_t; - -enum vfs_op { - VFSOP_OPEN, - VFSOP_READ, - VFSOP_WRITE, - VFSOP_GETSIZE, - VFSOP_REMOVE, - VFSOP_CLOSE, -}; - -struct ufs_request { - enum vfs_op op; - size_t len; // how much was put in *buf - size_t capacity; // how much output can be accepted by the caller - void __user *id; // file id (returned by the open handler, passed to other calls) - long offset; - int flags; -}; - -struct intr_data { - void __user *ip; - void __user *sp; /* last for pop %rsp */ -}; - -struct sys_wait2 { - long status; -}; diff --git a/src/shared/include/shared/mem.h b/src/shared/include/shared/mem.h deleted file mode 100644 index 3597edf..0000000 --- a/src/shared/include/shared/mem.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once -#include <stdarg.h> -#include <stddef.h> - -/* note: (partially) tested in the userland tests */ - -void *memchr(const void *s, int c, size_t n); -int memcmp(const void *s1, const void *s2, size_t n); - -void *memcpy(void *dest, const void *src, size_t n); -void *memmove(void *dest, const void *src, size_t n); -void *memset(void *s, int c, size_t n); - -int strcmp(const char *s1, const char *s2); -size_t strlen(const char *s); - -int snprintf(char *restrict str, size_t len, const char *restrict fmt, ...); -int vsnprintf(char *restrict str, size_t len, const char *restrict fmt, va_list ap); diff --git a/src/shared/include/shared/printf.h b/src/shared/include/shared/printf.h deleted file mode 100644 index 45fd358..0000000 --- a/src/shared/include/shared/printf.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once -#include <stdarg.h> -#include <stddef.h> - -int __printf_internal(const char *fmt, va_list argp, - void (*back)(void*, const char*, size_t), void *back_arg); diff --git a/src/shared/include/shared/ring.h b/src/shared/include/shared/ring.h deleted file mode 100644 index dbaf331..0000000 --- a/src/shared/include/shared/ring.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once -#include <stddef.h> -#include <stdint.h> - -typedef struct { - char *buf; - size_t capacity; - size_t _head, _tail; -} ring_t; - -/** Returns amount of bytes stored in the buffer. */ -size_t ring_used(ring_t*); -/** Returns amount of space left in the buffer. */ -size_t ring_avail(ring_t*); - -void ring_put(ring_t*, const void*, size_t); -void ring_put1b(ring_t*, uint8_t); - -size_t ring_get(ring_t*, void*, size_t); - -/** Consumes up to `len` bytes, and returns a pointer to the buffer where it's stored. - * Not thread-safe. */ -void* ring_contig(ring_t*, size_t *len); diff --git a/src/shared/mem.c b/src/shared/mem.c deleted file mode 100644 index 14dd6bd..0000000 --- a/src/shared/mem.c +++ /dev/null @@ -1,82 +0,0 @@ -#include <assert.h> -#include <shared/mem.h> -#include <stdint.h> - -union dualptr_const { const uintptr_t *w; const char *c; uintptr_t u; }; -union dualptr { uintptr_t *w; char *c; uintptr_t u; }; - -void *memchr(const void *s, int c, size_t n) { - const unsigned char *s2 = s; - for (size_t i = 0; i < n; i++) { - if (s2[i] == (unsigned char)c) - return (void*)&s2[i]; - } - return NULL; -} - -int memcmp(const void *s1, const void *s2, size_t n) { - const unsigned char *c1 = s1, *c2 = s2; - for (size_t i = 0; i < n; i++) { - if (c1[i] != c2[i]) { - if (c1[i] < c2[i]) return -1; - else return 1; - } - } - return 0; -} - -void *memcpy(void *dest, const void *src, size_t n) { - // TODO erms, rep movsb - union dualptr_const s = {.c = src}; - union dualptr d = {.c = dest}; - if (dest == src) return dest; - // assert(src >= dest || src + n < dest); - - for (; (d.u & 7) && n != 0; n--) { - *(d.c)++ = *(s.c)++; - } - while (n >= sizeof(uintptr_t)) { - *(d.w)++ = *(s.w)++; - n -= sizeof(uintptr_t); - } - while (n-- != 0) { - *(d.c)++ = *(s.c)++; - } - return dest; -} - -void *memmove(void *dest, const void *src, size_t n) { - if (src >= dest || src + n < dest) - return memcpy(dest, src, n); - for (; n; n--) /* naive reverse copy */ - ((uint8_t*)dest)[n-1] = ((uint8_t*)src)[n-1]; - return dest; -} - -void *memset(void *s, int c, size_t n) { - union dualptr d = {.c = s}; - - uintptr_t fill = (c & 0xff) * 0x0101010101010101; - while (n >= sizeof(uintptr_t)) { - *(d.w)++ = fill; - n -= sizeof(uintptr_t); - } - while (n-- != 0) - *(d.c)++ = c; - return s; -} - -int strcmp(const char *s1, const char *s2) { - while (*s1 && *s1 == *s2) { - s1++; s2++; - } - if (*s1 == *s2) return 0; - if (*s1 < *s2) return -1; - else return 1; -} - -size_t strlen(const char *s) { - size_t c = 0; - while (*s++) c++; - return c; -} diff --git a/src/shared/path.c b/src/shared/path.c deleted file mode 100644 index 4e3077b..0000000 --- a/src/shared/path.c +++ /dev/null @@ -1,53 +0,0 @@ -#include <assert.h> -#include <camellia/path.h> -#include <shared/mem.h> -#include <stdbool.h> - -size_t path_simplify(const char *in, char *out, size_t len) { - if (len == 0) return 0; /* empty paths are invalid */ - if (in[0] != '/') return 0; /* so are relative paths */ - - int seg_len; - int out_pos = 0; - bool directory = false; - - for (size_t i = 0; i < len; i += seg_len + 1) { - assert(in[i] == '/'); - - seg_len = 0; - directory = false; - for (size_t j = i + 1; j < len; j++) { - if (in[j] == '/') { - directory = true; - break; - } - seg_len++; - } - - /* |i=5 |next i = i + seg_len + 1 = 10 - * v v - * /some/path/asdf - * |--| - * seg_len = 4, segment starts at i+1 */ - - if (seg_len == 0 || (seg_len == 1 && in[i + 1] == '.')) { - /* // or /./ */ - directory = true; - } else if (seg_len == 2 && in[i + 1] == '.' && in[i + 2] == '.') { - /* /../ */ - directory = true; - /* try to backtrack to the last slash */ - while (--out_pos >= 0 && out[out_pos] != '/'); - if (out_pos < 0) return 0; - } else { - /* a normal segment, e.g. /asdf/ */ - out[out_pos] = '/'; - memcpy(&out[out_pos + 1], &in[i + 1], seg_len); - out_pos += seg_len + 1; - } - } - - if (directory) out[out_pos++] = '/'; - assert(0 < out_pos && (size_t)out_pos <= len); - return out_pos; -} diff --git a/src/shared/printf.c b/src/shared/printf.c deleted file mode 100644 index fffd801..0000000 --- a/src/shared/printf.c +++ /dev/null @@ -1,268 +0,0 @@ -#include <shared/mem.h> -#include <shared/printf.h> -#include <stdarg.h> -#include <stdbool.h> -#include <stdint.h> - -enum lenmod { - LM_int, - LM_long, - LM_longlong, - LM_size, -}; - -struct out_state { - void (*back)(void *, const char *, size_t); - void *backarg; - int written; - - char *cache; - size_t cpos, clen; -}; - -struct mods { - char fill_char; - size_t field_width; - size_t precision; -}; - - -static int flush(struct out_state *os) { - if (os->cpos) { - os->back(os->backarg, os->cache, os->cpos); - os->written += os->cpos; - os->cpos = 0; - } - return os->written; -} - -static void output(struct out_state *os, const char *buf, size_t len) { - if (os->cpos + len < os->clen) { - memcpy(os->cache + os->cpos, buf, len); - os->cpos += len; - return; - } - flush(os); - os->back(os->backarg, buf, len); - os->written += len; -} - -static void output_c(struct out_state *os, char c, int amt) { - for (int i = 0; i < amt; i++) - output(os, &c, 1); -} - - -static void pad(struct out_state *os, struct mods *m, size_t len) { - output_c(os, m->fill_char, m->field_width - len); -} - -static void padnum(struct out_state *os, struct mods *m, size_t len, char sign) { - if (len < m->precision) { - output_c(os, m->fill_char, m->field_width - m->precision - (sign ? 1 : 0)); - if (sign) output_c(os, sign, 1); - output_c(os, '0', m->precision - len); - } else { - output_c(os, m->fill_char, m->field_width - len - (sign ? 1 : 0)); - if (sign) output_c(os, sign, 1); - } -} - -static void output_uint(struct out_state *os, struct mods *m, unsigned long long n, char sign) { - char buf[sizeof(unsigned long long) * 3]; - size_t pos = sizeof(buf); - - if (!n) { - buf[--pos] = '0'; - } else while (n) { - unsigned long long q = n / 10, r = n % 10; - buf[--pos] = r + '0'; - n = q; - } - size_t len = sizeof(buf) - pos; - padnum(os, m, len, sign); - output(os, buf + pos, len); -} - -static void output_uint16(struct out_state *os, struct mods *m, unsigned long long n) { - size_t len = 1; - while (n >> (len * 4) && (len * 4) < (sizeof(n) * 8)) - len++; - padnum(os, m, len, '\0'); - while (len-- > 0) { - char h = '0' + ((n >> (len * 4)) & 0xf); - if (h > '9') h += 'a' - '9' - 1; - output_c(os, h, 1); - } -} - - -int __printf_internal(const char *fmt, va_list argp, - void (*back)(void*, const char*, size_t), void *backarg) -{ - const char *seg = fmt; /* beginning of the current non-modifier streak */ - char cache[64]; - struct out_state os = { - .back = back, - .backarg = backarg, - .cache = cache, - .cpos = 0, - .clen = sizeof(cache), - }; - - for (;;) { - char c = *fmt++; - if (c == '\0') { - output(&os, seg, fmt - seg - 1); - return flush(&os); - } - if (c != '%') continue; - output(&os, seg, fmt - seg - 1); - - struct mods m = { - .fill_char = ' ', - .field_width = 0, - .precision = 0, - }; - - for (bool modifier = true; modifier;) { - c = *fmt++; - switch (c) { - case '0': - m.fill_char = '0'; - break; - default: - modifier = false; - break; - } - } - - while ('0' <= c && c <= '9') { - m.field_width *= 10; - m.field_width += c - '0'; - c = *fmt++; - } - - if (c == '.') { - c = *fmt++; - if (c == '*') { - // TODO handle negative precision - m.precision = va_arg(argp, int); - c = *fmt++; - } else while ('0' <= c && c <= '9') { - m.precision *= 10; - m.precision += c - '0'; - c = *fmt++; - } - } - - enum lenmod lm; - switch (c) { - case 'l': - lm = LM_long; - c = *fmt++; - if (c == 'l') { - lm = LM_longlong; - c = *fmt++; - } - break; - case 'z': - lm = LM_size; - c = *fmt++; - break; - default: - lm = LM_int; - break; - } - - switch (c) { - unsigned long n, len; - long ns; - char sign; - - case 'c': - output_c(&os, va_arg(argp, int), 1); - break; - - case 's': - const char *s = va_arg(argp, char*); - if (s == NULL) s = "(null)"; - // TODO can segfault even if precision caps the string - len = strlen(s); - if (len > m.precision && m.precision != 0) - len = m.precision; - pad(&os, &m, len); - output(&os, s, len); - break; - - case 'p': - output(&os, "0x", 2); - output_uint16(&os, &m, (uintptr_t)va_arg(argp, void*)); - break; - - case 'x': - if (lm == LM_int) n = va_arg(argp, unsigned int); - else if (lm == LM_long) n = va_arg(argp, unsigned long); - else if (lm == LM_longlong) n = va_arg(argp, unsigned long long); - else if (lm == LM_size) n = va_arg(argp, size_t); - output_uint16(&os, &m, n); - break; - - case 'u': - if (lm == LM_int) n = va_arg(argp, unsigned int); - else if (lm == LM_long) n = va_arg(argp, unsigned long); - else if (lm == LM_longlong) n = va_arg(argp, unsigned long long); - else if (lm == LM_size) n = va_arg(argp, size_t); - output_uint(&os, &m, n, '\0'); - break; - - case 'd': - case 'i': - if (lm == LM_int) ns = va_arg(argp, int); - else if (lm == LM_long) ns = va_arg(argp, long); - else if (lm == LM_longlong) ns = va_arg(argp, long long); - else if (lm == LM_size) ns = va_arg(argp, size_t); - sign = '\0'; - if (ns < 0) { - ns = -ns; - sign = '-'; - } - output_uint(&os, &m, (long)ns, sign); - break; - - case '%': - output(&os, "%", 1); - break; - } - seg = fmt; - } -} - - -static void vsnprintf_backend(void *arg, const char *buf, size_t len) { - char **ptrs = arg; - size_t space = ptrs[1] - ptrs[0]; - if (!ptrs[0]) return; - if (len > space) len = space; - - memcpy(ptrs[0], buf, len); - ptrs[0] += len; - /* ptrs[1] is the last byte of the buffer, it must be 0. - * on overflow: - * ptrs[0] + (ptrs[1] - ptrs[0]) = ptrs[1] */ - *ptrs[0] = '\0'; -} - -int vsnprintf(char *restrict str, size_t len, const char *restrict fmt, va_list ap) { - char *ptrs[2] = {str, str + len - 1}; - return __printf_internal(fmt, ap, vsnprintf_backend, &ptrs); -} - -int snprintf(char *restrict str, size_t len, const char *restrict fmt, ...) { - int ret; - va_list argp; - va_start(argp, fmt); - ret = vsnprintf(str, len, fmt, argp); - va_end(argp); - return ret; -} diff --git a/src/shared/ring.c b/src/shared/ring.c deleted file mode 100644 index 44c73f6..0000000 --- a/src/shared/ring.c +++ /dev/null @@ -1,60 +0,0 @@ -#include <shared/ring.h> -#include <shared/mem.h> -#include <stdbool.h> - -static bool at_end(ring_t *r) { - return r->_head + 1 == r->_tail - || (r->_head + 1 == r->capacity && r->_tail == 0); -} - -size_t ring_used(ring_t *r) { - if (r->_head >= r->_tail) - return r->_head - r->_tail; - else - return r->_head + r->capacity - r->_tail; -} - -size_t ring_avail(ring_t *r) { - return r->capacity - ring_used(r); -} - -void ring_put(ring_t *r, const void *buf, size_t len) { - // TODO do something similar to ring_get - for (size_t i = 0; i < len; i++) - ring_put1b(r, ((uint8_t*)buf)[i]); -} - -void ring_put1b(ring_t *r, uint8_t byte) { - if (at_end(r)) return; - r->buf[r->_head++] = byte; - if (r->_head >= r->capacity) r->_head = 0; -} - -size_t ring_get(ring_t *r, void *buf, size_t len) { - size_t read = 0; - size_t plen; - void *pbuf; - for (size_t i = 0; i < 2; i++) { - plen = len - read; - pbuf = ring_contig(r, &plen); - if (buf) memcpy(buf + read, pbuf, plen); - read += plen; - } - return read; -} - -void *ring_contig(ring_t *r, size_t *len) { - void *ret = &r->buf[r->_tail]; - size_t avail; - if (r->_head >= r->_tail) - avail = r->_head - r->_tail; - else - avail = r->capacity - r->_tail; - - if (*len > avail) - *len = avail; - - r->_tail += *len; - if (r->_tail >= r->capacity) r->_tail = 0; - return ret; -} |