Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers...
[reactos.git] / modules / rosapps / applications / net / ncftp / sio / URecvfrom.c
diff --git a/modules/rosapps/applications/net/ncftp/sio/URecvfrom.c b/modules/rosapps/applications/net/ncftp/sio/URecvfrom.c
new file mode 100644 (file)
index 0000000..d119391
--- /dev/null
@@ -0,0 +1,63 @@
+#include "syshdrs.h"
+
+#if !defined(NO_UNIX_DOMAIN_SOCKETS) && !defined(NO_SIGNALS)
+
+extern volatile Sjmp_buf gNetTimeoutJmp;
+extern volatile Sjmp_buf gPipeJmp;
+
+int
+URecvfrom(int sfd, char *const buf, size_t size, int fl, struct sockaddr_un *const fromAddr, int *ualen, int tlen)
+{
+       int nread, tleft;
+       vsio_sigproc_t sigalrm, sigpipe;
+       time_t done, now;
+
+       if (SSetjmp(gNetTimeoutJmp) != 0) {
+               alarm(0);
+               (void) SSignal(SIGALRM, (sio_sigproc_t) sigalrm);
+               (void) SSignal(SIGPIPE, (sio_sigproc_t) sigpipe);
+               errno = ETIMEDOUT;
+               return (kTimeoutErr);
+       }
+
+       if (SSetjmp(gPipeJmp) != 0) {
+               alarm(0);
+               (void) SSignal(SIGALRM, (sio_sigproc_t) sigalrm);
+               (void) SSignal(SIGPIPE, (sio_sigproc_t) sigpipe);
+               errno = EPIPE;
+               return (kBrokenPipeErr);
+       }
+
+       sigalrm = (vsio_sigproc_t) SSignal(SIGALRM, SIOHandler);
+       sigpipe = (vsio_sigproc_t) SSignal(SIGPIPE, SIOHandler);
+
+       time(&now);
+       done = now + tlen;
+       tleft = (int) (done - now);
+       forever {
+               *ualen = sizeof(struct sockaddr_un);
+               (void) alarm((unsigned int) tleft);
+               nread = recvfrom(sfd, buf, size, fl,
+                       (struct sockaddr *) fromAddr, ualen);
+               (void) alarm(0);
+               if (nread >= 0)
+                       break;
+               if (errno != EINTR)
+                       break;          /* Fatal error. */
+               errno = 0;
+               time(&now);
+               tleft = (int) (done - now);
+               if (tleft < 1) {
+                       nread = kTimeoutErr;
+                       errno = ETIMEDOUT;
+                       break;
+               }
+       }
+
+       (void) SSignal(SIGALRM, (sio_sigproc_t) sigalrm);
+       (void) SSignal(SIGPIPE, (sio_sigproc_t) sigpipe);
+
+       return (nread);
+}      /* URecvfrom */
+
+#endif