📄 pth_syscall.c
字号:
/*** GNU Pth - The GNU Portable Threads** Copyright (c) 1999-2004 Ralf S. Engelschall <rse@engelschall.com>**** This file is part of GNU Pth, a non-preemptive thread scheduling** library which can be found at http://www.gnu.org/software/pth/.**** This library is free software; you can redistribute it and/or** modify it under the terms of the GNU Lesser General Public** License as published by the Free Software Foundation; either** version 2.1 of the License, or (at your option) any later version.**** This library is distributed in the hope that it will be useful,** but WITHOUT ANY WARRANTY; without even the implied warranty of** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU** Lesser General Public License for more details.**** You should have received a copy of the GNU Lesser General Public** License along with this library; if not, write to the Free Software** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307** USA, or contact Ralf S. Engelschall <rse@engelschall.com>.**** pth_syscall.c: Pth direct syscall support*/ /* ``Free Software: generous programmers from around the world all join forces to help you shoot yourself in the foot for free.'' -- Unknown *//* * Prevent system includes from declaring the syscalls in order to avoid * prototype mismatches. In theory those mismatches should not happen * at all, but slight (but still compatible) differences (ssize_t vs. * size_t, etc) can lead to a compile-time failure (although run-time * would be ok). Hence protect ourself from this situation. */#define fork __pth_sys_fork#define waitpid __pth_sys_waitpid#define system __pth_sys_system#define nanosleep __pth_sys_nanosleep#define usleep __pth_sys_usleep#define sleep __pth_sys_sleep#define sigprocmask __pth_sys_sigmask#define sigwait __pth_sys_sigwait#define select __pth_sys_select#define pselect __pth_sys_pselect#define poll __pth_sys_poll#define connect __pth_sys_connect#define accept __pth_sys_accept#define read __pth_sys_read#define write __pth_sys_write#define readv __pth_sys_readv#define writev __pth_sys_writev#define recv __pth_sys_recv#define send __pth_sys_send#define recvfrom __pth_sys_recvfrom#define sendto __pth_sys_sendto#define pread __pth_sys_pread#define pwrite __pth_sys_pwrite/* include the private header and this way system headers */#include "pth_p.h"/* some exported variables for object layer checks */int pth_syscall_soft = PTH_SYSCALL_SOFT;int pth_syscall_hard = PTH_SYSCALL_HARD;#if cpp#if PTH_SYSCALL_HARD/* hard syscall mapping */#if HAVE_SYS_SYSCALL_H#include <sys/syscall.h>#endif#ifdef HAVE_SYS_SOCKETCALL_H#include <sys/socketcall.h>#endif#define pth_sc(func) pth_sc_##func#else /* !PTH_SYSCALL_HARD *//* no hard syscall mapping */#define pth_sc(func) func#endif /* PTH_SYSCALL_HARD */#endif /* cpp *//* * Unprotect us from the namespace conflict with the * syscall prototypes in system headers. */#undef fork#undef waitpid#undef system#undef nanosleep#undef usleep#undef sleep#undef sigprocmask#undef sigwait#undef select#undef pselect#undef poll#undef connect#undef accept#undef read#undef write#undef readv#undef writev#undef recv#undef send#undef recvfrom#undef sendto#undef pread#undef pwrite/* internal data structures */#if cpptypedef int (*pth_syscall_fct_t)();typedef struct { char *name; /* name of system/function call */ pth_syscall_fct_t addr; /* address of wrapped system/function call */} pth_syscall_fct_tab_t;typedef struct { char *path; /* path to dynamic library */ void *handle; /* handle of dynamic library */} pth_syscall_lib_tab_t;#endif#if PTH_SYSCALL_HARD/* NUL-spiked copy of library paths */static char *pth_syscall_libs = NULL;/* table of dynamic libraries and their resolving handles */static pth_syscall_lib_tab_t pth_syscall_lib_tab[128] = { { NULL, NULL }};/* table of syscalls and their resolved function pointers */intern pth_syscall_fct_tab_t pth_syscall_fct_tab[] = { /* Notice: order must match the macro values above */#define PTH_SCF_fork 0#define PTH_SCF_waitpid 1#define PTH_SCF_system 2#define PTH_SCF_nanosleep 3#define PTH_SCF_usleep 4#define PTH_SCF_sleep 5#define PTH_SCF_sigprocmask 6#define PTH_SCF_sigwait 7#define PTH_SCF_select 8#define PTH_SCF_poll 9#define PTH_SCF_connect 10#define PTH_SCF_accept 11#define PTH_SCF_read 12#define PTH_SCF_write 13#define PTH_SCF_readv 14#define PTH_SCF_writev 15#define PTH_SCF_recv 16#define PTH_SCF_send 17#define PTH_SCF_recvfrom 18#define PTH_SCF_sendto 19#define PTH_SCF_pread 20#define PTH_SCF_pwrite 21 { "fork", NULL }, { "waitpid", NULL }, { "system", NULL }, { "nanosleep", NULL }, { "usleep", NULL }, { "sleep", NULL }, { "sigprocmask", NULL }, { "sigwait", NULL }, { "select", NULL }, { "poll", NULL }, { "connect", NULL }, { "accept", NULL }, { "read", NULL }, { "write", NULL }, { "readv", NULL }, { "writev", NULL }, { "recv", NULL }, { "send", NULL }, { "recvfrom", NULL }, { "sendto", NULL }, { "pread", NULL }, { "pwrite", NULL }, { NULL, NULL }};#endif/* syscall wrapping initialization */intern void pth_syscall_init(void){#if PTH_SYSCALL_HARD int i; int j; char *cpLib; char *cp; /* fill paths of libraries into internal table */ pth_syscall_libs = strdup(PTH_SYSCALL_LIBS); cpLib = pth_syscall_libs; for (i = 0; i < (sizeof(pth_syscall_lib_tab)/sizeof(pth_syscall_lib_tab_t))-1; ) { if ((cp = strchr(cpLib, ':')) != NULL) *cp++ = '\0'; pth_syscall_lib_tab[i].path = cpLib; pth_syscall_lib_tab[i].handle = NULL; i++; if (cp != NULL) cpLib = cp; else break; } pth_syscall_lib_tab[i].path = NULL;#if defined(HAVE_DLOPEN) && defined(HAVE_DLSYM) /* determine addresses of syscall functions */ for (i = 0; pth_syscall_fct_tab[i].name != NULL; i++) { /* attempt #1: fetch from implicit successor libraries */#if defined(HAVE_DLSYM) && defined(HAVE_RTLD_NEXT) pth_syscall_fct_tab[i].addr = (pth_syscall_fct_t) dlsym(RTLD_NEXT, pth_syscall_fct_tab[i].name);#endif /* attempt #2: fetch from explicitly loaded C library */ if (pth_syscall_fct_tab[i].addr == NULL) { /* first iteration: try resolve from already loaded libraries */ for (j = 0; pth_syscall_lib_tab[j].path != NULL; j++) { if (pth_syscall_lib_tab[j].handle != NULL) { pth_syscall_fct_tab[i].addr = (pth_syscall_fct_t) dlsym(pth_syscall_lib_tab[j].handle, pth_syscall_fct_tab[i].name); if (pth_syscall_fct_tab[i].addr != NULL) break; } } /* second iteration: try to load more libraries for resolving */ if (pth_syscall_fct_tab[i].addr == NULL) { for (j = 0; pth_syscall_lib_tab[j].path != NULL; j++) { if (pth_syscall_lib_tab[j].handle == NULL) { if ((pth_syscall_lib_tab[j].handle = dlopen(pth_syscall_lib_tab[j].path, RTLD_LAZY)) == NULL) continue; pth_syscall_fct_tab[i].addr = (pth_syscall_fct_t) dlsym(pth_syscall_lib_tab[j].handle, pth_syscall_fct_tab[i].name); if (pth_syscall_fct_tab[i].addr != NULL) break; } } } } }#endif#endif return;}/* syscall wrapping initialization */intern void pth_syscall_kill(void){#if PTH_SYSCALL_HARD int i;#if defined(HAVE_DLOPEN) && defined(HAVE_DLSYM) /* unload all explicitly loaded libraries */ for (i = 0; pth_syscall_lib_tab[i].path != NULL; i++) { if (pth_syscall_lib_tab[i].handle != NULL) { dlclose(pth_syscall_lib_tab[i].handle); pth_syscall_lib_tab[i].handle = NULL; } pth_syscall_lib_tab[i].path = NULL; }#endif free(pth_syscall_libs); pth_syscall_libs = NULL;#endif return;}#if PTH_SYSCALL_HARD/* utility macro for returning syscall errors */#define PTH_SYSCALL_ERROR(return_val,errno_val,syscall) \ do { fprintf(stderr, \ "pth:WARNING: unable to perform syscall `%s': " \ "no implementation resolvable\n", syscall); \ errno = (errno_val); \ return (return_val); \ } while (0)/* ==== Pth hard syscall wrapper for fork(2) ==== */pid_t fork(void);pid_t fork(void){ /* external entry point for application */ pth_implicit_init(); return pth_fork();}intern pid_t pth_sc_fork(void){ /* internal exit point for Pth */ if (pth_syscall_fct_tab[PTH_SCF_fork].addr != NULL) return ((pid_t (*)(void)) pth_syscall_fct_tab[PTH_SCF_fork].addr) ();#if defined(HAVE_SYSCALL) && defined(SYS_fork) else return (pid_t)syscall(SYS_fork);#else else PTH_SYSCALL_ERROR(-1, ENOSYS, "fork");#endif}/* ==== Pth hard syscall wrapper for nanosleep(3) ==== */int nanosleep(const struct timespec *, struct timespec *);int nanosleep(const struct timespec *rqtp, struct timespec *rmtp){ /* external entry point for application */ pth_implicit_init(); return pth_nanosleep(rqtp, rmtp);}/* NOTICE: internally fully emulated, so still no internal exit point pth_sc_nanosleep necessary! *//* ==== Pth hard syscall wrapper for usleep(3) ==== */int usleep(unsigned int);int usleep(unsigned int sec){ /* external entry point for application */ pth_implicit_init(); return pth_usleep(sec);}/* NOTICE: internally fully emulated, so still no internal exit point pth_sc_usleep necessary! *//* ==== Pth hard syscall wrapper for sleep(3) ==== */unsigned int sleep(unsigned int);unsigned int sleep(unsigned int sec){ /* external entry point for application */ pth_implicit_init(); return pth_sleep(sec);}/* NOTICE: internally fully emulated, so still no internal exit point pth_sc_sleep necessary! *//* ==== Pth hard syscall wrapper for system(3) ==== */int system(const char *);int system(const char *cmd){ /* external entry point for application */ pth_implicit_init(); return pth_system(cmd);}/* NOTICE: internally fully emulated, so still no internal exit point pth_sc_system necessary! *//* ==== Pth hard syscall wrapper for sigprocmask(2) ==== */int sigprocmask(int, const sigset_t *, sigset_t *);int sigprocmask(int how, const sigset_t *set, sigset_t *oset){ /* external entry point for application */ pth_implicit_init(); return pth_sigmask(how, set, oset);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -