OSSP CVS Repository

ossp - Difference in ossp-pkg/pth/pth_syscall.c versions 1.22 and 1.23
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [History

ossp-pkg/pth/pth_syscall.c 1.22 -> 1.23

--- 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 */
 

CVSTrac 2.0.1