📄 syscalls.c
字号:
/* * syscalls.c * * Copyright (c) 1996, 1997 * Transvirtual Technologies, Inc. All rights reserved. * * See the file "license.terms" for information on usage and redistribution * of this file. */#include "config.h"#include "config-std.h"#include "config-mem.h"#include "config-io.h"#include "config-signal.h"#include "config-net.h"#include "jthread.h"#include "jsyscall.h"#include "nets.h"/* * This file contains thread-safe version of various POSIXy functions. * Other functions that use or interact with asynchronous I/O, are in jthread.c. */static intjthreadedClose(int fd){ int rc = 0; jthread_spinon(0); if (close(fd) == -1) { rc = errno; } jthread_spinoff(0); return (rc);}static intjthreadedSocketShutdown(int fd){ int rc = 0; jthread_spinon(0); if (shutdown(fd, 2) == -1) rc = errno; jthread_spinoff(0); return rc;}static intjthreadedListen(int fd, int l){ int rc = 0; jthread_spinon(0); if (listen(fd, l) == -1) { rc = errno; } jthread_spinoff(0); return (rc);}static intjthreadedKill(int pid, int sig){ int rc = 0; jthread_spinon(0); if (kill(pid, sig) == -1) { rc = errno; } jthread_spinoff(0); return (rc);}static intjthreadedBind(int fd, struct sockaddr *addr, int namelen){ int rc = 0; jthread_spinon(0); if (bind(fd, addr, (size_t)namelen) == -1) { rc = errno; } jthread_spinoff(0); return (rc);}static intjthreadedLSeek(int fd, off_t offset, int whence, off_t *out){ int rc = 0; jthread_spinon(0); *out = lseek(fd, offset, whence); if (*out == -1) { rc = errno; } jthread_spinoff(0); return (rc);}static intjthreadedFStat(int fd, struct stat *sb){ int rc = 0; jthread_spinon(0); if (fstat(fd, sb) == -1) { rc = errno; } jthread_spinoff(0); return (rc);}static intjthreadedStat(const char* path, struct stat *sb){ int rc = 0; jthread_spinon(0); if (stat(path, sb) == -1) { rc = errno; } jthread_spinoff(0); return (rc);}static intjthreadedFTruncate(int fd, off_t new_size){#ifdef HAVE_FTRUNCATE int rc = 0; jthread_spinon(0); if (ftruncate(fd, new_size) == -1) { rc = errno; } jthread_spinoff(0); return (rc);#else return ENOTSUP;#endif}static intjthreadedFSync(int fd){#ifdef HAVE_FSYNC int rc = 0; jthread_spinon(0); if (fsync(fd) == -1) { rc = errno; } jthread_spinoff(0); return (rc);#else return ENOTSUP;#endif}static intjthreadedMkdir(const char *path, int mode){ int rc = 0; jthread_spinon(0); if (mkdir(path, (unsigned)mode) == -1) { rc = errno; } jthread_spinoff(0); return (rc);}static intjthreadedRmdir(const char *path){ int rc = 0; jthread_spinon(0); if (rmdir(path) == -1) { rc = errno; } jthread_spinoff(0); return (rc);}static intjthreadedRename(const char *path1, const char *path2){ int rc = 0; jthread_spinon(0); if (rename(path1, path2) == -1) { rc = errno; } jthread_spinoff(0); return (rc);}static intjthreadedRemove(const char *entry){ int rc = 0; jthread_spinon(0); if (remove(entry) == -1) { rc = errno; } jthread_spinoff(0); return (rc);}static int jthreadedSendto(int a, const void* b, size_t c, int d, const struct sockaddr* e, size_t f, ssize_t *out){ int rc = 0; jthread_spinon(0); *out = e ? sendto(a, b, c, d, e, f) : send(a, b, c, d); if (*out == -1) { rc = errno; } jthread_spinoff(0); return (rc);}static intjthreadedSetSockOpt(int a, int b, int c, const void* d, int e){ int rc = 0; jthread_spinon(0); if (setsockopt(a, b, c, d, (unsigned)e) == -1) { rc = errno; } jthread_spinoff(0); return (rc);}static intjthreadedGetSockOpt(int a, int b, int c, void* d, socklen_t* e){ int rc = 0; jthread_spinon(0); if (getsockopt(a, b, c, d, e) == -1) { rc = errno; } jthread_spinoff(0); return (rc);}static intjthreadedGetSockName(int a, struct sockaddr* b, socklen_t* c){ int rc = 0; jthread_spinon(0); if (getsockname(a, b, c) == -1) { rc = errno; } jthread_spinoff(0); return (rc);}static intjthreadedGetPeerName(int a, struct sockaddr* b, socklen_t* c){ int rc = 0; jthread_spinon(0); if (getpeername(a, b, c) == -1) { rc = errno; } jthread_spinoff(0); return (rc);}static intjthreadedGetHostByName(const char *host, struct hostent** out){ int rc = 0; jthread_spinon(0); /* NB: this will block the whole process while we're looking up * a name. However, gethostbyname is extremely async-signal-unsafe, * and hence we have no other choice. Now I understand why old * Netscapes blocked when looking up a name. * * In a UNIXy system, a possible solution is to spawn a process * for lookups, which I think is what NS eventually did. */ *out = gethostbyname(host); if (*out == 0) { rc = h_errno; if (rc == 0) { *out = (void*)-1; rc = errno; } } jthread_spinoff(0); return (rc);}static intjthreadedGetHostByAddr(const char *host, int l, int t, struct hostent** out){ int rc = 0; jthread_spinon(0); /* NB: same comment as for jthreadedGetHostByName applies here */ *out = gethostbyaddr(host, (unsigned)l, t); if (*out == 0) { rc = h_errno; if (rc == 0) { *out = (void*)-1; rc = errno; } } jthread_spinoff(0); return (rc);}static intjthreadedMmap(void **memory, size_t *size, int mode, int fd, off_t *offset){#if defined(HAVE_MMAP) size_t pages_sz; off_t pages_offset; int sysmode, sysflags; int rc = 0; pages_sz = (*size)/getpagesize(); *size = (pages_sz+1)*getpagesize(); pages_offset = (*offset)/getpagesize(); *offset = pages_offset*getpagesize(); switch (mode) { case KAFFE_MMAP_READ: sysflags = MAP_PRIVATE; sysmode = PROT_READ; break; case KAFFE_MMAP_WRITE: sysflags = MAP_SHARED; sysmode = PROT_READ | PROT_WRITE; break; case KAFFE_MMAP_PRIVATE: sysflags = MAP_PRIVATE; sysmode = PROT_WRITE | PROT_READ; break; default: return EINVAL; } jthread_spinon(0); *memory = mmap(*memory, *size, sysmode, sysflags, fd, *offset); if (*memory == NULL) rc = errno; jthread_spinoff(0); return (rc);#else return (ENOTSUP);#endif}static intjthreadedMunmap(void *memory, size_t size){#if defined(HAVE_MMAP) int rc = 0; jthread_spinon(0); if (munmap(memory, size) < 0) { rc = errno; } jthread_spinoff(0); return (rc);#else return (ENOTSUP);#endif}static intjthreadedMsync(void *memory, size_t size){#if defined(HAVE_MMAP) int rc = 0; jthread_spinon(0); memory = (void *)(((size_t)memory/getpagesize()) * getpagesize()); size += getpagesize(); /* TODO: Try not to freeze the entire VM. */ if (msync(memory, size, MS_SYNC | MS_INVALIDATE) < 0) { rc = errno; } jthread_spinoff(0); return rc;#else return (ENOTSUP);#endif}/* * The syscall interface as provided by the internal jthread system. */SystemCallInterface Kaffe_SystemCallInterface = { jthreadedOpen, jthreadedRead, jthreadedWrite, jthreadedLSeek, jthreadedClose, jthreadedFStat, jthreadedStat, jthreadedFTruncate, jthreadedFSync, jthreadedMkdir, jthreadedRmdir, jthreadedRename, jthreadedRemove, jthreadedSocket, jthreadedConnect, jthreadedBind, jthreadedListen, jthreadedAccept, jthreadedTimedRead, jthreadedRecvfrom, jthreadedWrite, jthreadedSendto, jthreadedSetSockOpt, jthreadedGetSockOpt, jthreadedGetSockName, jthreadedGetPeerName, jthreadedClose, jthreadedSocketShutdown, jthreadedGetHostByName, jthreadedGetHostByAddr, jthreadedSelect, jthreadedForkExec, jthreadedWaitpid, jthreadedKill, jthreadedMmap, jthreadedMunmap, jthreadedMsync, jthreadedPipeCreate, jthreadedTimedRead, jthreadedTimedWrite};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -