--- 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 <sys/syscall.h>
+#endif
#ifdef HAVE_SYS_SOCKETCALL_H
#include <sys/socketcall.h>
#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 */
|