Index: ossp-pkg/pth/ChangeLog RCS File: /v/ossp/cvs/ossp-pkg/pth/ChangeLog,v rcsdiff -q -kk '-r1.570' '-r1.571' -u '/v/ossp/cvs/ossp-pkg/pth/ChangeLog,v' 2>/dev/null --- ChangeLog 2002/10/15 21:14:27 1.570 +++ ChangeLog 2002/10/20 11:45:10 1.571 @@ -21,6 +21,20 @@ Changes between 1.4.1 and 1.5.0 (27-Jan-2002 to xx-Sep-2002) + *) Completely rewrote the "hard syscall mapping". + + Previously the internal syscall exit points were based on syscall(2) + only. This is problematic because it by-passes the C library glue + code which sometimes performs necessary assembly fiddling in order + to call the underlying system calls correctly. Additionally, + syscall(2) does not exists everywhere. + + Now the internal exit points are based on a by-syscall dynamically + selected combination of RTLD_NEXT+dlsym(2), dlopen(2)+dlsym(2) and + the known syscall(2) (in this fallback order). This way the "hard + syscall mapping" is a lot more portable and flexible. + [Ralf S. Engelschall, Jonathan Schilling ] + *) Added support to pth_poll(3) for the poll(2) XPG.4 flags POLLD{RD,WR}{NORM,BAND}. [Jason Evans , Ralf S. Engelschall] Index: ossp-pkg/pth/configure.ac RCS File: /v/ossp/cvs/ossp-pkg/pth/configure.ac,v rcsdiff -q -kk '-r1.5' '-r1.6' -u '/v/ossp/cvs/ossp-pkg/pth/configure.ac,v' 2>/dev/null --- configure.ac 2002/10/15 20:34:22 1.5 +++ configure.ac 2002/10/20 11:45:10 1.6 @@ -463,10 +463,46 @@ AC_MSG_PART(System Call Mapping) -AC_CHECK_FUNCS(syscall) +dnl # check for syscall(2) AC_CHECK_HEADERS(sys/syscall.h sys/socketcall.h) +AC_CHECK_FUNCS(syscall) AC_CHECK_DEFINE(SYS_read, sys/syscall.h) +dnl # check for dlsym(3) with RTLD_NEXT +AC_CHECK_HEADERS(dlfcn.h) +AC_CHECK_LIB(dl, dlsym) +AC_CHECK_FUNCS(dlopen dlsym dlclose) +AC_CHECK_DEFINE(RTLD_NEXT, dlfcn.h) + +dnl # check for path to dynamic C library +AC_MSG_CHECKING([for syscall dynamic libraries]) +pth_syscall_libs="" +dirs=`echo "$LDFLAGS" |\ + sed -e 's;-L\([[^ ]]*\);<\1>;g' |\ + sed -e 's;^[[^<]]*<;;' -e 's;>[[^<]]*<; ;g' -e 's;>.*$;;'` +dirs="$dirs /usr/lib /lib" +libs=`echo "$LIBS" |\ + sed -e 's;-l\([[^ ]]*\);<\1>;g' |\ + sed -e 's;^[[^<]]*<;;' -e 's;>[[^<]]*<; ;g' -e 's;>.*$;;'` +libs="$libs c" +for lib in $libs; do + for dir in $dirs; do + for ext in so sl; do + if test -f "${dir}/lib${lib}.${ext}"; then + if test ".$pth_syscall_libs" = .; then + pth_syscall_libs="${dir}/lib${lib}.${ext}" + else + pth_syscall_libs="${pth_syscall_libs}:${dir}/lib${lib}.${ext}" + fi + fi + done + done +done +AC_MSG_RESULT([$pth_syscall_libs]) +AC_DEFINE_UNQUOTED(PTH_SYSCALL_LIBS, + ["$pth_syscall_libs"], + [define for the paths to syscall dynamic libraries]) + AC_MSG_CHECKING([whether soft system call mapping is used]) AC_ARG_ENABLE(syscall-soft,dnl [ --enable-syscall-soft enable soft system call mapping (default=no)], Index: ossp-pkg/pth/pth_lib.c RCS File: /v/ossp/cvs/ossp-pkg/pth/pth_lib.c,v rcsdiff -q -kk '-r1.50' '-r1.51' -u '/v/ossp/cvs/ossp-pkg/pth/pth_lib.c,v' 2>/dev/null --- pth_lib.c 2002/10/15 20:34:22 1.50 +++ pth_lib.c 2002/10/20 11:45:10 1.51 @@ -69,6 +69,9 @@ pth_debug1("pth_init: enter"); + /* initialize syscall wrapping */ + pth_syscall_init(); + /* initialize the scheduler */ pth_scheduler_init(); @@ -138,6 +141,7 @@ pth_initialized = FALSE; pth_tcb_free(pth_sched); pth_tcb_free(pth_main); + pth_syscall_kill(); #ifdef PTH_EX __ex_ctx = __ex_ctx_default; __ex_terminate = __ex_terminate_default; Index: ossp-pkg/pth/pth_p.h.in RCS File: /v/ossp/cvs/ossp-pkg/pth/pth_p.h.in,v rcsdiff -q -kk '-r1.31' '-r1.32' -u '/v/ossp/cvs/ossp-pkg/pth/pth_p.h.in,v' 2>/dev/null --- pth_p.h.in 2002/01/30 13:34:40 1.31 +++ pth_p.h.in 2002/10/20 11:45:10 1.32 @@ -64,6 +64,9 @@ #ifdef HAVE_NET_ERRNO_H #include #endif +#ifdef HAVE_DLFCN_H +#include +#endif /* dmalloc support */ #ifdef PTH_DMALLOC Index: ossp-pkg/pth/pth_syscall.c RCS File: /v/ossp/cvs/ossp-pkg/pth/pth_syscall.c,v rcsdiff -q -kk '-r1.22' '-r1.23' -u '/v/ossp/cvs/ossp-pkg/pth/pth_syscall.c,v' 2>/dev/null --- pth_syscall.c 2002/01/27 11:03:41 1.22 +++ pth_syscall.c 2002/10/20 11:45:10 1.23 @@ -29,309 +29,535 @@ -- Unknown */ #include "pth_p.h" -#if cpp +/* 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 +#endif #ifdef HAVE_SYS_SOCKETCALL_H #include #endif -#define pth_sc(func) PTH_SC_##func -#else +#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 */ + +/* internal data structures */ +#if cpp +#if PTH_SYSCALL_HARD +typedef 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 #endif -#endif /* cpp */ +#if PTH_SYSCALL_HARD -/* some exported variables for object layer checks */ -int pth_syscall_soft = PTH_SYSCALL_SOFT; -int pth_syscall_hard = PTH_SYSCALL_HARD; +/* NUL-spiked copy of library paths */ +static char *pth_syscall_libs = NULL; -/* Pth hard wrapper for syscall fork(2) */ -#if cpp -#if defined(SYS_fork) -#define PTH_SC_fork() ((pid_t)syscall(SYS_fork)) -#else -#define PTH_SC_fork fork +/* 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_sleep 3 +#define PTH_SCF_sigprocmask 4 +#define PTH_SCF_sigwait 5 +#define PTH_SCF_select 6 +#define PTH_SCF_poll 7 +#define PTH_SCF_connect 8 +#define PTH_SCF_accept 9 +#define PTH_SCF_read 10 +#define PTH_SCF_write 11 +#define PTH_SCF_readv 12 +#define PTH_SCF_writev 13 +#define PTH_SCF_recv 14 +#define PTH_SCF_send 15 +#define PTH_SCF_recvfrom 16 +#define PTH_SCF_sendto 17 +#define PTH_SCF_pread 18 +#define PTH_SCF_pwrite 19 + { "fork", NULL }, + { "waitpid", NULL }, + { "system", 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 -#endif /* cpp */ -#if PTH_SYSCALL_HARD && defined(SYS_fork) + +/* 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) { + /* 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 wrapper for sleep(3) [internally fully emulated] */ -#if PTH_SYSCALL_HARD +/* ==== Pth hard syscall wrapper for sleep(3) ==== */ unsigned int sleep(unsigned int sec) { + /* external entry point for application */ pth_implicit_init(); return pth_sleep(sec); } -#endif +/* NOTICE: internally fully emulated, so still no + internal exit point pth_sc_sleep necessary! */ -/* Pth hard wrapper for system(3) [internally fully emulated] */ -#if PTH_SYSCALL_HARD +/* ==== Pth hard syscall wrapper for system(3) ==== */ int system(const char *cmd) { + /* external entry point for application */ pth_implicit_init(); return pth_system(cmd); } -#endif +/* NOTICE: internally fully emulated, so still no + internal exit point pth_sc_system necessary! */ -/* Pth hard wrapper for sigprocmask(2) */ -#if cpp -#if defined(SYS_sigprocmask) -#define PTH_SC_sigprocmask(a1,a2,a3) ((int)syscall(SYS_sigprocmask,(a1),(a2),(a3))) -#else -#define PTH_SC_sigprocmask sigprocmask -#endif -#endif /* cpp */ -#if PTH_SYSCALL_HARD && defined(SYS_sigprocmask) +/* ==== Pth hard syscall wrapper for sigprocmask(2) ==== */ 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); } +intern int pth_sc_sigprocmask(int how, const sigset_t *set, sigset_t *oset) +{ + /* internal exit point for Pth */ + if (pth_syscall_fct_tab[PTH_SCF_sigprocmask].addr != NULL) + return ((int (*)(int, const sigset_t *, sigset_t *)) + pth_syscall_fct_tab[PTH_SCF_sigprocmask].addr) + (how, set, oset); +#if defined(HAVE_SYSCALL) && defined(SYS_sigprocmask) + else return (int)syscall(SYS_sigprocmask, how, set, oset); +#else + else PTH_SYSCALL_ERROR(-1, ENOSYS, "sigprocmask"); #endif +} -/* Pth hard wrapper for sigwait(3) [internally fully emulated] */ -#if PTH_SYSCALL_HARD +/* ==== Pth hard syscall wrapper for sigwait(3) ==== */ int sigwait(const sigset_t *set, int *sigp) { + /* external entry point for application */ pth_implicit_init(); return pth_sigwait(set, sigp); } -#endif +/* NOTICE: internally fully emulated, so still no + internal exit point pth_sc_sigwait necessary! */ -/* Pth hard wrapper for syscall waitpid(2) */ -#if cpp -#if defined(SYS_waitpid) -#define PTH_SC_waitpid(a1,a2,a3) ((int)syscall(SYS_waitpid,(a1),(a2),(a3))) -#else -#define PTH_SC_waitpid waitpid -#endif -#endif /* cpp */ -#if PTH_SYSCALL_HARD && defined(SYS_waitpid) +/* ==== Pth hard syscall wrapper for waitpid(2) ==== */ pid_t waitpid(pid_t wpid, int *status, int options) { + /* external entry point for application */ pth_implicit_init(); return pth_waitpid(wpid, status, options); } -#endif - -#if defined(SYS_socketcall) && defined(SOCKOP_connect) && defined(SOCKOP_accept) /* mainly Linux */ -intern int _pth_socketcall(int call, ...) +intern pid_t pth_sc_waitpid(pid_t wpid, int *status, int options) { - va_list ap; - unsigned long args[3]; - - va_start(ap, call); - switch (call) { - case SOCKOP_connect: - args[0] = (unsigned long)va_arg(ap, int); - args[1] = (unsigned long)va_arg(ap, struct sockaddr *); - args[2] = (unsigned long)va_arg(ap, int); - break; - case SOCKOP_accept: - args[0] = (unsigned long)va_arg(ap, int); - args[1] = (unsigned long)va_arg(ap, struct sockaddr *); - args[2] = (unsigned long)va_arg(ap, int *); - break; - } - va_end(ap); - return syscall(SYS_socketcall, call, args); -} -#endif - -/* Pth hard wrapper for syscall connect(2) */ -#if cpp -#if defined(SYS_connect) -#define PTH_SC_connect(a1,a2,a3) ((int)syscall(SYS_connect,(a1),(a2),(a3))) -#elif defined(SYS_socketcall) && defined(SOCKOP_connect) /* mainly Linux */ -#define PTH_SC_connect(a1,a2,a3) ((int)_pth_socketcall(SOCKOP_connect,(a1),(a2),(a3))) + /* internal exit point for Pth */ + if (pth_syscall_fct_tab[PTH_SCF_waitpid].addr != NULL) + return ((pid_t (*)(pid_t, int *, int)) + pth_syscall_fct_tab[PTH_SCF_waitpid].addr) + (wpid, status, options); +#if defined(HAVE_SYSCALL) && defined(SYS_waitpid) + else return (pid_t)syscall(SYS_waitpid, wpid, status, options); #else -#define PTH_SC_connect connect + else PTH_SYSCALL_ERROR(-1, ENOSYS, "waitpid"); #endif -#endif /* cpp */ -#if PTH_SYSCALL_HARD &&\ - (defined(SYS_connect) || (defined(SYS_socketcall) && defined(SOCKOP_connect))) +} + +/* ==== Pth hard syscall wrapper for connect(2) ==== */ int connect(int s, const struct sockaddr *addr, socklen_t addrlen) { + /* external entry point for application */ pth_implicit_init(); return pth_connect(s, addr, addrlen); } -#endif - -/* Pth hard wrapper for syscall accept(2) */ -#if cpp -#if defined(SYS_accept) -#define PTH_SC_accept(a1,a2,a3) ((int)syscall(SYS_accept,(a1),(a2),(a3))) -#elif defined(SYS_socketcall) && defined(SOCKOP_accept) /* mainly Linux */ -#define PTH_SC_accept(a1,a2,a3) ((int)_pth_socketcall(SOCKOP_accept,(a1),(a2),(a3))) +intern int pth_sc_connect(int s, const struct sockaddr *addr, socklen_t addrlen) +{ + /* internal exit point for Pth */ + if (pth_syscall_fct_tab[PTH_SCF_connect].addr != NULL) + return ((int (*)(int, const struct sockaddr *, socklen_t)) + pth_syscall_fct_tab[PTH_SCF_connect].addr) + (s, addr, addrlen); +#if defined(HAVE_SYSCALL) && defined(SYS_connect) + else return (int)syscall(SYS_connect, s, addr, addrlen); +#elif defined(HAVE_SYSCALL) && defined(SYS_socketcall) && defined(SOCKOP_connect) + else { + unsigned long args[3]; + args[0] = (unsigned long)s; + args[1] = (unsigned long)addr; + args[2] = (unsigned long)addrlen; + return (int)syscall(SYS_socketcall, SOCKOP_connect, args); + } #else -#define PTH_SC_accept accept + else PTH_SYSCALL_ERROR(-1, ENOSYS, "connect"); #endif -#endif /* cpp */ -#if PTH_SYSCALL_HARD &&\ - (defined(SYS_accept) || (defined(SYS_socketcall) && defined(SOCKOP_accept))) +} + +/* ==== Pth hard syscall wrapper for accept(2) ==== */ int accept(int s, struct sockaddr *addr, socklen_t *addrlen) { + /* external entry point for application */ pth_implicit_init(); return pth_accept(s, addr, addrlen); } -#endif - -/* Pth hard wrapper for syscall select(2) */ -#if cpp -#if defined(SYS__newselect) /* mainly Linux */ -#define PTH_SC_select(a1,a2,a3,a4,a5) ((int)syscall(SYS__newselect,(a1),(a2),(a3),(a4),(a5))) -#elif defined(SYS_select) -#define PTH_SC_select(a1,a2,a3,a4,a5) ((int)syscall(SYS_select,(a1),(a2),(a3),(a4),(a5))) +intern int pth_sc_accept(int s, struct sockaddr *addr, socklen_t *addrlen) +{ + /* internal exit point for Pth */ + if (pth_syscall_fct_tab[PTH_SCF_accept].addr != NULL) + return ((int (*)(int, struct sockaddr *, socklen_t *)) + pth_syscall_fct_tab[PTH_SCF_accept].addr) + (s, addr, addrlen); +#if defined(HAVE_SYSCALL) && defined(SYS_accept) + else return (int)syscall(SYS_accept, s, addr, addrlen); +#elif defined(HAVE_SYSCALL) && defined(SYS_socketcall) && defined(SOCKOP_accept) + else { + unsigned long args[3]; + args[0] = (unsigned long)s; + args[1] = (unsigned long)addr; + args[2] = (unsigned long)addrlen; + return (int)syscall(SYS_socketcall, SOCKOP_accept, args); + } #else -#define PTH_SC_select select + else PTH_SYSCALL_ERROR(-1, ENOSYS, "accept"); #endif -#endif /* cpp */ -#if PTH_SYSCALL_HARD && (defined(SYS__newselect) || defined(SYS_select)) +} + +/* ==== Pth hard syscall wrapper for select(2) ==== */ int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) { + /* external entry point for application */ pth_implicit_init(); return pth_select(nfds, readfds, writefds, exceptfds, timeout); } -#endif - -/* Pth hard wrapper for syscall poll(2) */ -#if cpp -#if defined(SYS_poll) -#define PTH_SC_poll(a1,a2,a3) ((int)syscall(SYS_poll,(a1),(a2),(a3))) +intern int pth_sc_select(int nfds, fd_set *readfds, fd_set *writefds, + fd_set *exceptfds, struct timeval *timeout) +{ + /* internal exit point for Pth */ + if (pth_syscall_fct_tab[PTH_SCF_select].addr != NULL) + return ((int (*)(int, fd_set *, fd_set *, fd_set *, struct timeval *)) + pth_syscall_fct_tab[PTH_SCF_select].addr) + (nfds, readfds, writefds, exceptfds, timeout); +#if defined(HAVE_SYSCALL) && defined(SYS__newselect) + else return (int)syscall(SYS__newselect, nfds, readfds, writefds, exceptfds, timeout); +#elif defined(HAVE_SYSCALL) && defined(SYS_select) + else return (int)syscall(SYS_select, nfds, readfds, writefds, exceptfds, timeout); #else -#define PTH_SC_poll poll + else PTH_SYSCALL_ERROR(-1, ENOSYS, "accept"); #endif -#endif /* cpp */ -#if PTH_SYSCALL_HARD && defined(SYS_poll) +} + +/* ==== Pth hard syscall wrapper for poll(2) ==== */ int poll(struct pollfd *pfd, nfds_t nfd, int timeout) { + /* external entry point for application */ pth_implicit_init(); return pth_poll(pfd, nfd, timeout); } -#endif +/* NOTICE: internally fully emulated, so still no + internal exit point pth_sc_poll necessary! */ -/* Pth hard wrapper for syscall read(2) */ -#if cpp -#if defined(SYS_read) -#define PTH_SC_read(a1,a2,a3) ((ssize_t)syscall(SYS_read,(a1),(a2),(a3))) -#else -#define PTH_SC_read read -#endif -#endif /* cpp */ -#if PTH_SYSCALL_HARD && defined(SYS_read) +/* ==== Pth hard syscall wrapper for read(2) ==== */ ssize_t read(int fd, void *buf, size_t nbytes) { + /* external entry point for application */ pth_implicit_init(); return pth_read(fd, buf, nbytes); } -#endif - -/* Pth hard wrapper for syscall write(2) */ -#if cpp -#if defined(SYS_write) -#define PTH_SC_write(a1,a2,a3) ((ssize_t)syscall(SYS_write,(a1),(a2),(a3))) +intern ssize_t pth_sc_read(int fd, void *buf, size_t nbytes) +{ + /* internal exit point for Pth */ + if (pth_syscall_fct_tab[PTH_SCF_read].addr != NULL) + return ((ssize_t (*)(int, void *, size_t)) + pth_syscall_fct_tab[PTH_SCF_read].addr) + (fd, buf, nbytes); +#if defined(HAVE_SYSCALL) && defined(SYS_read) + else return (ssize_t)syscall(SYS_read, fd, buf, nbytes); #else -#define PTH_SC_write write + else PTH_SYSCALL_ERROR(-1, ENOSYS, "read"); #endif -#endif /* cpp */ -#if PTH_SYSCALL_HARD && defined(SYS_write) +} + +/* ==== Pth hard syscall wrapper for write(2) ==== */ ssize_t write(int fd, const void *buf, size_t nbytes) { + /* external entry point for application */ pth_implicit_init(); return pth_write(fd, buf, nbytes); } -#endif - -/* Pth hard wrapper for syscall readv(2) */ -#if cpp -#if defined(SYS_readv) -#define PTH_SC_readv(a1,a2,a3) ((ssize_t)syscall(SYS_readv,(a1),(a2),(a3))) +intern ssize_t pth_sc_write(int fd, const void *buf, size_t nbytes) +{ + /* internal exit point for Pth */ + if (pth_syscall_fct_tab[PTH_SCF_write].addr != NULL) + return ((ssize_t (*)(int, const void *, size_t)) + pth_syscall_fct_tab[PTH_SCF_write].addr) + (fd, buf, nbytes); +#if defined(HAVE_SYSCALL) && defined(SYS_write) + else return (ssize_t)syscall(SYS_write, fd, buf, nbytes); #else -#define PTH_SC_readv readv + else PTH_SYSCALL_ERROR(-1, ENOSYS, "write"); #endif -#endif /* cpp */ -#if PTH_SYSCALL_HARD && defined(SYS_readv) +} + +/* ==== Pth hard syscall wrapper for readv(2) ==== */ ssize_t readv(int fd, const struct iovec *iov, int iovcnt) { + /* external entry point for application */ pth_implicit_init(); return pth_readv(fd, iov, iovcnt); } -#endif - -/* Pth hard wrapper for syscall writev(2) */ -#if cpp -#if defined(SYS_writev) -#define PTH_SC_writev(a1,a2,a3) ((ssize_t)syscall(SYS_writev,(a1),(a2),(a3))) +intern ssize_t pth_sc_readv(int fd, const struct iovec *iov, int iovcnt) +{ + /* internal exit point for Pth */ + if (pth_syscall_fct_tab[PTH_SCF_readv].addr != NULL) + return ((ssize_t (*)(int, const struct iovec *, int)) + pth_syscall_fct_tab[PTH_SCF_readv].addr) + (fd, iov, iovcnt); +#if defined(HAVE_SYSCALL) && defined(SYS_readv) + else return (ssize_t)syscall(SYS_readv, fd, iov, iovcnt); #else -#define PTH_SC_writev writev + else PTH_SYSCALL_ERROR(-1, ENOSYS, "readv"); #endif -#endif /* cpp */ -#if PTH_SYSCALL_HARD && defined(SYS_writev) +} + +/* ==== Pth hard syscall wrapper for writev(2) ==== */ ssize_t writev(int fd, const struct iovec *iov, int iovcnt) { + /* external entry point for application */ pth_implicit_init(); return pth_writev(fd, iov, iovcnt); } +intern ssize_t pth_sc_writev(int fd, const struct iovec *iov, int iovcnt) +{ + /* internal exit point for Pth */ + if (pth_syscall_fct_tab[PTH_SCF_writev].addr != NULL) + return ((ssize_t (*)(int, const struct iovec *, int)) + pth_syscall_fct_tab[PTH_SCF_writev].addr) + (fd, iov, iovcnt); +#if defined(HAVE_SYSCALL) && defined(SYS_writev) + else return (ssize_t)syscall(SYS_writev, fd, iov, iovcnt); +#else + else PTH_SYSCALL_ERROR(-1, ENOSYS, "writev"); #endif +} -/* Pth hard wrapper for pread(3) [internally fully emulated] */ -#if PTH_SYSCALL_HARD +/* ==== Pth hard syscall wrapper for pread(2) ==== */ ssize_t pread(int, void *, size_t, off_t); ssize_t pread(int fd, void *buf, size_t nbytes, off_t offset) { + /* external entry point for application */ pth_implicit_init(); return pth_pread(fd, buf, nbytes, offset); } -#endif +/* NOTICE: internally fully emulated, so still no + internal exit point pth_sc_pread necessary! */ -/* Pth hard wrapper for pwrite(3) [internally fully emulated] */ -#if PTH_SYSCALL_HARD +/* ==== Pth hard syscall wrapper for pwrite(2) ==== */ ssize_t pwrite(int, const void *, size_t, off_t); ssize_t pwrite(int fd, const void *buf, size_t nbytes, off_t offset) { + /* external entry point for application */ pth_implicit_init(); return pth_pwrite(fd, buf, nbytes, offset); } -#endif +/* NOTICE: internally fully emulated, so still no + internal exit point pth_sc_pwrite necessary! */ -/* Pth hard wrapper for syscall recvfrom(2) */ -#if cpp -#if defined(SYS_recvfrom) -#define PTH_SC_recvfrom(a1,a2,a3,a4,a5,a6) ((ssize_t)syscall(SYS_recvfrom,(a1),(a2),(a3),(a4),(a5),(a6))) -#else -#define PTH_SC_recvfrom recvfrom -#endif -#endif /* cpp */ -#if PTH_SYSCALL_HARD && defined(SYS_recvfrom) +/* ==== Pth hard syscall wrapper for recvfrom(2) ==== */ ssize_t recvfrom(int fd, void *buf, size_t nbytes, int flags, struct sockaddr *from, socklen_t *fromlen) { + /* external entry point for application */ pth_implicit_init(); return pth_recvfrom(fd, buf, nbytes, flags, from, fromlen); } -#endif - -/* Pth hard wrapper for syscall sendto(2) */ -#if cpp -#if defined(SYS_sendto) -#define PTH_SC_sendto(a1,a2,a3,a4,a5,a6) ((ssize_t)syscall(SYS_sendto,(a1),(a2),(a3),(a4),(a5),(a6))) +intern ssize_t pth_sc_recvfrom(int fd, void *buf, size_t nbytes, int flags, struct sockaddr *from, socklen_t *fromlen) +{ + /* internal exit point for Pth */ + if (pth_syscall_fct_tab[PTH_SCF_recvfrom].addr != NULL) + return ((ssize_t (*)(int, void *, size_t, int, struct sockaddr *, socklen_t *)) + pth_syscall_fct_tab[PTH_SCF_recvfrom].addr) + (fd, buf, nbytes, flags, from, fromlen); +#if defined(HAVE_SYSCALL) && defined(SYS_recvfrom) + else return (ssize_t)syscall(SYS_recvfrom, fd, buf, nbytes, flags, from, fromlen); #else -#define PTH_SC_sendto sendto + else PTH_SYSCALL_ERROR(-1, ENOSYS, "recvfrom"); #endif -#endif /* cpp */ -#if PTH_SYSCALL_HARD && defined(SYS_sendto) +} + +/* ==== Pth hard syscall wrapper for sendto(2) ==== */ ssize_t sendto(int fd, const void *buf, size_t nbytes, int flags, const struct sockaddr *to, socklen_t tolen) { + /* external entry point for application */ pth_implicit_init(); return pth_sendto(fd, buf, nbytes, flags, to, tolen); } +intern ssize_t pth_sc_sendto(int fd, const void *buf, size_t nbytes, int flags, const struct sockaddr *to, socklen_t tolen) +{ + /* internal exit point for Pth */ + if (pth_syscall_fct_tab[PTH_SCF_sendto].addr != NULL) + return ((ssize_t (*)(int, const void *, size_t, int, const struct sockaddr *, socklen_t)) + pth_syscall_fct_tab[PTH_SCF_recvfrom].addr) + (fd, buf, nbytes, flags, to, tolen); +#if defined(HAVE_SYSCALL) && defined(SYS_sendto) + else return (ssize_t)syscall(SYS_sendto, fd, buf, nbytes, flags, to, tolen); +#else + else PTH_SYSCALL_ERROR(-1, ENOSYS, "sendto"); #endif +} + +#endif /* PTH_SYSCALL_HARD */