#include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <stdbool.h> #include <stdarg.h> #include <string.h> #include <uchar.h> #include <err.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> #include "fake-lib.h" char *ascii(const char16_t *wstr, bool translate_slashes) { size_t len = 0; for (const char16_t *wp = wstr; *wp; wp++) len++; char *ret = malloc(len + 1); char *p = ret; for (const char16_t *wp = wstr; *wp; wp++) *p++ = (*wp == '\\' && translate_slashes ? '/' : *wp < 0x80 ? *wp : '?'); *p = '\0'; return ret; } void system_argv_array(char **args) { pid_t pid = fork(); if (pid < 0) err(1, "fork"); if (pid == 0) { execvp(args[0], args); warn("execvp"); _exit(127); } int status; if (waitpid(pid, &status, 0) != pid) err(1, "waitpid"); if (!(WIFEXITED(status) && WEXITSTATUS(status) == 0)) errx(1, "subcommand failed"); } void system_argv(const char *cmd, ...) { int nargs, nchars; const char *word; va_list ap; va_start(ap, cmd); nargs = 1; /* terminating NULL */ nchars = 0; for (word = cmd; word; word = va_arg(ap, const char *)) { nargs++; nchars += 1 + strlen(word); } va_end(ap); char *args[nargs], chars[nchars]; char **argp = args, *charp = chars; va_start(ap, cmd); for (word = cmd; word; word = va_arg(ap, const char *)) { *argp++ = charp; strcpy(charp, word); charp += 1 + strlen(word); } va_end(ap); *argp++ = NULL; system_argv_array(args); } void c16cpy(char16_t *out, uint32_t *outsize, char *s) { uint32_t retlen = 0; while (retlen < *outsize) { char16_t c = (out[retlen] = (unsigned char)*s++); if (!c) break; retlen++; } *outsize = retlen; } void *smalloc(size_t size) { void *toret = malloc(size); if (!toret) errx(1, "out of memory"); return toret; } void *srealloc(void *ptr, size_t size) { void *toret = realloc(ptr, size); if (!toret) errx(1, "out of memory"); return toret; } char *dupcat(const char *str, ...) { va_list ap; const char *p; char *out, *outp; size_t len; len = 1; va_start(ap, str); for (p = str; p; p = va_arg(ap, const char *)) len += strlen(p); va_end(ap); out = snewn(len, char); outp = out; va_start(ap, str); for (p = str; p; p = va_arg(ap, const char *)) { strcpy(outp, p); outp += strlen(p); } va_end(ap); return out; } unsigned le(const unsigned char *buf, size_t len, size_t off, size_t nbytes) { unsigned toret = 0; off += nbytes; while (nbytes-- > 0) { toret <<= 8; if (--off < len) toret |= buf[off]; } return toret; }