Path: blob/main/system/lib/libc/emscripten_libc_stubs.c
6162 views
/*1* Copyright 2021 The Emscripten Authors. All rights reserved.2* Emscripten is available under two separate licenses, the MIT license and the3* University of Illinois/NCSA Open Source License. Both these licenses can be4* found in the LICENSE file.5*6* Fake/stub implementations of libc functions.7* See emscripten_syscall_stubs.c for fake/stub implementations of syscalls.8*/910#include <errno.h>11#include <grp.h>12#include <pwd.h>13#include <string.h>14#include <time.h>15#include <signal.h>16#include <spawn.h>17#include <stdio.h>18#include <sys/times.h>19#include <sys/wait.h>20#include <unistd.h>2122#ifndef weak23#define weak __attribute__((__weak__))24#endif2526// ==========================================================================27// sys/wait.h28// ==========================================================================2930weak int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options) {31errno = ECHILD;32return -1;33}3435// ==========================================================================36// sys/times.h37// ==========================================================================3839clock_t times(struct tms *buf) {40// clock_t times(struct tms *buffer);41// http://pubs.opengroup.org/onlinepubs/009695399/functions/times.html42// NOTE: This is fake, since we can't calculate real CPU time usage in JS.43if (buf) {44memset(buf, 0, sizeof(*buf));45}46return 0;47}4849struct tm *getdate(const char *string) {50// struct tm *getdate(const char *string);51// http://pubs.opengroup.org/onlinepubs/009695399/functions/getdate.html52// TODO: Implement.53return 0;54}5556weak int stime(const time_t *t) {57errno = EPERM;58return -1;59}6061weak int clock_getcpuclockid(pid_t pid, clockid_t *clockid) {62if (pid < 0) {63return ESRCH;64}65if (pid != 0 && pid != getpid()) {66return ENOSYS;67}68if (clockid) {69*clockid = CLOCK_PROCESS_CPUTIME_ID;70}71return 0;72}7374// ==========================================================================75// pwd.h76// ==========================================================================7778struct passwd *getpwnam(const char *name) {79errno = ENOENT;80return 0;81}8283struct passwd *getpwuid(uid_t uid) {84errno = ENOENT;85return 0;86}8788weak int getpwnam_r(const char *name, struct passwd *pwd,89char *buf, size_t buflen, struct passwd **result) {90return ENOENT;91}9293weak int getpwuid_r(uid_t uid, struct passwd *pwd,94char *buf, size_t buflen, struct passwd **result) {95return ENOENT;96}9798weak void setpwent(void) {99}100101weak void endpwent(void) {102}103104struct passwd *getpwent(void) {105errno = EIO;106return NULL;107}108109// ==========================================================================110// grp.h111// ==========================================================================112113weak struct group *getgrnam(const char *name) {114errno = ENOENT;115return 0;116}117118weak struct group *getgrgid(gid_t gid) {119errno = ENOENT;120return 0;121}122123weak int getgrnam_r(const char *name, struct group *grp,124char *buf, size_t buflen, struct group **result) {125return ENOENT;126}127128weak int getgrgid_r(gid_t gid, struct group *grp,129char *buf, size_t buflen, struct group **result) {130return ENOENT;131}132133weak struct group *getgrent(void) {134errno = EIO;135return NULL;136}137138weak void endgrent(void) {139}140141weak void setgrent(void) {142}143144// ==========================================================================145// sys/file.h146// ==========================================================================147148weak int flock(int fd, int operation) {149// Pretend that the locking is successful. These are process-level locks,150// and Emscripten programs are a single process. If we supported linking a151// filesystem between programs, we'd need to do more here.152// See https://github.com/emscripten-core/emscripten/issues/23697153return 0;154}155156weak int chroot(const char *path) {157// int chroot(const char *path);158// http://pubs.opengroup.org/onlinepubs/7908799/xsh/chroot.html159errno = EACCES;160return -1;161}162163weak int execve(const char *pathname, char *const argv[],164char *const envp[]) {165// int execve(const char *pathname, char *const argv[],166// char *const envp[]);167// http://pubs.opengroup.org/onlinepubs/009695399/functions/exec.html168// We don't support executing external code.169errno = ENOEXEC;170return -1;171}172173weak pid_t fork(void) {174// pid_t fork(void);175// http://pubs.opengroup.org/onlinepubs/000095399/functions/fork.html176// We don't support multiple processes.177errno = ENOSYS;178return -1;179}180181weak pid_t vfork(void) {182errno = ENOSYS;183return -1;184}185186weak int posix_spawn(pid_t *pid, const char *path,187const posix_spawn_file_actions_t *file_actions,188const posix_spawnattr_t *attrp,189char *const argv[], char *const envp[]) {190errno = ENOSYS;191return -1;192}193194// ==========================================================================195// stdio.h196// ==========================================================================197198weak FILE *popen(const char *command, const char *type) {199errno = ENOSYS;200return NULL;201}202203weak int pclose(FILE *stream) {204errno = ENOSYS;205return -1;206}207208weak int setgroups(size_t size, const gid_t *list) {209// int setgroups(int ngroups, const gid_t *gidset);210// https://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man2/setgroups.2.html211if (size < 1 || size > sysconf(_SC_NGROUPS_MAX)) {212errno = EINVAL;213return -1;214}215// We have just one process/user/group, so it makes no sense to set groups.216errno = EPERM;217return -1;218}219220weak int sigaltstack(const stack_t *restrict ss, stack_t *restrict old_ss) {221errno = ENOSYS;222return -1;223}224225// ==========================================================================226// dlfcn.h227// ==========================================================================228229#ifndef EMSCRIPTEN_DYNAMIC_LINKING230void __dl_seterr(const char*, ...);231232weak void *__dlsym(void *restrict p, const char *restrict s, void *restrict ra) {233__dl_seterr("dynamic linking not enabled");234return NULL;235}236237weak void* dlopen(const char* file, int flags) {238__dl_seterr("dynamic linking not enabled");239return NULL;240}241#endif242243// ==========================================================================244// stdlib.h245// ==========================================================================246247#define MIN(x, y) (((x) < (y)) ? (x) : (y))248249weak int getloadavg(double loadavg[], int nelem) {250// http://linux.die.net/man/3/getloadavg251int limit = MIN(nelem, 3);252for (int i = 0; i < limit; i++) {253loadavg[i] = 0.1;254}255return limit;256}257258259