Ejemplo n.º 1
0
int
SSendtoByName(int sfd, const char *const buf, size_t size, int fl, const char *const toAddrStr, int tlen)
{
    int nwrote, tleft, result;
    vsio_sigproc_t sigalrm, sigpipe;
    time_t done, now;
    struct sockaddr_in toAddr;

    if ((result = AddrStrToAddr(toAddrStr, &toAddr, -1)) < 0) {
        return (result);
    }

    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 {
        (void) alarm((unsigned int) tleft);
        nwrote = sendto(sfd, buf, size, fl,
                        (struct sockaddr *) &toAddr,
                        (int) sizeof(struct sockaddr_in));
        (void) alarm(0);
        if (nwrote >= 0)
            break;
        if (errno != EINTR)
            break;		/* Fatal error. */
        errno = 0;
        time(&now);
        tleft = (int) (done - now);
        if (tleft < 1) {
            nwrote = kTimeoutErr;
            errno = ETIMEDOUT;
            break;
        }
    }

    (void) SSignal(SIGALRM, (sio_sigproc_t) sigalrm);
    (void) SSignal(SIGPIPE, (sio_sigproc_t) sigpipe);

    return (nwrote);
}	/* SSendtoByName */
Ejemplo n.º 2
0
int
SRecvfrom(int sfd, char *const buf, size_t size, int fl, struct sockaddr_in *const fromAddr, int tlen)
{
	int nread, tleft;
	vsio_sigproc_t sigalrm, sigpipe;
	time_t done, now;
	int alen;

	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 {
		alen = sizeof(struct sockaddr_in);
		(void) alarm((unsigned int) tleft);
		nread = recvfrom(sfd, buf, size, fl,
			(struct sockaddr *) fromAddr, &alen);
		(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);
}	/* SRecvfrom */
Ejemplo n.º 3
0
int
PWrite(int sfd, const char *const buf0, size_t size)
{
	volatile int nleft;
	const char *volatile buf = buf0;
	int nwrote;
#if !defined(NO_SIGNALS) && defined(SIGPIPE)
	vsio_sigproc_t sigpipe;

	if (SSetjmp(gPipeJmp) != 0) {
		(void) SSignal(SIGPIPE, (sio_sigproc_t) sigpipe);
		nwrote = size - nleft;
		if (nwrote > 0)
			return (nwrote);
		errno = EPIPE;
		return (kBrokenPipeErr);
	}

	sigpipe = (vsio_sigproc_t) SSignal(SIGPIPE, SIOHandler);
#endif

	nleft = (int) size;
	forever {
		nwrote = write(sfd, buf, nleft);
		if (nwrote < 0) {
			if (errno != EINTR) {
				nwrote = size - nleft;
				if (nwrote == 0)
					nwrote = -1;
				goto done;
			} else {
				errno = 0;
				nwrote = 0;
				/* Try again. */
			}
		}
		nleft -= nwrote;
		if (nleft <= 0)
			break;
		buf += nwrote;
	}
	nwrote = size - nleft;

done:
#if !defined(NO_SIGNALS) && defined(SIGPIPE)
	(void) SSignal(SIGPIPE, (sio_sigproc_t) sigpipe);
#endif

	return (nwrote);
}	/* PWrite */
Ejemplo n.º 4
0
int
SAcceptA(int sfd, struct sockaddr_in *const addr, int tlen)
{
	int result;
#ifndef NO_SIGNALS
	vsio_sigproc_t sigalrm, sigpipe;
#endif
	size_t size;

	if (tlen < 0) {
		errno = 0;
		for (;;) {
			size = sizeof(struct sockaddr_in);
			result = accept(sfd, (struct sockaddr *) addr, (int *) &size);
			if ((result >= 0) || (errno != EINTR))
				return (result);
		}
	}
#ifndef NO_SIGNALS
	if (SSetjmp(gNetTimeoutJmp) != 0) {
		alarm(0);
		(void) SSignal(SIGALRM, (sio_sigproc_t) sigalrm);
		(void) SSignal(SIGPIPE, (sio_sigproc_t) sigpipe);
		errno = ETIMEDOUT;
		return (kTimeoutErr);
	}

	sigalrm = (vsio_sigproc_t) SSignal(SIGALRM, SIOHandler);
	sigpipe = (vsio_sigproc_t) SSignal(SIGPIPE, SIG_IGN);
	alarm((unsigned int) tlen);

	errno = 0;
	do {
		size = sizeof(struct sockaddr_in);
		result = accept(sfd, (struct sockaddr *) addr, (int *) &size);
	} while ((result < 0) && (errno == EINTR));

	alarm(0);
	(void) SSignal(SIGALRM, (sio_sigproc_t) sigalrm);
	(void) SSignal(SIGPIPE, (sio_sigproc_t) sigpipe);
	return (result);
#else
	return (-1);
#endif
}	/* SAcceptA */
Ejemplo n.º 5
0
int
UAcceptA(int sfd, struct sockaddr_un *const addr, int *ualen, int tlen)
{
	int result;
	vsio_sigproc_t sigalrm, sigpipe;

	if (tlen < 0) {
		errno = 0;
		for (;;) {
			*ualen = (int) sizeof(struct sockaddr_un);
			result = accept(sfd, (struct sockaddr *) addr, (int *) ualen);
			if ((result >= 0) || (errno != EINTR))
				return (result);
		}
	}

	if (SSetjmp(gNetTimeoutJmp) != 0) {
		alarm(0);
		(void) SSignal(SIGALRM, (sio_sigproc_t) sigalrm);
		(void) SSignal(SIGPIPE, (sio_sigproc_t) sigpipe);
		errno = ETIMEDOUT;
		return (kTimeoutErr);
	}

	sigalrm = (vsio_sigproc_t) SSignal(SIGALRM, SIOHandler);
	sigpipe = (vsio_sigproc_t) SSignal(SIGPIPE, SIG_IGN);
	alarm((unsigned int) tlen);

	errno = 0;
	do {
		*ualen = (int) sizeof(struct sockaddr_un);
		result = accept(sfd, (struct sockaddr *) addr, (int *) ualen);
	} while ((result < 0) && (errno == EINTR));

	alarm(0);
	(void) SSignal(SIGALRM, (sio_sigproc_t) sigalrm);
	(void) SSignal(SIGPIPE, (sio_sigproc_t) sigpipe);
	return (result);
}	/* UAcceptA */
Ejemplo n.º 6
0
int
SWrite(int sfd, const char *const buf0, size_t size, int tlen, int swopts)
{
    volatile int nleft;
    const char *volatile buf = buf0;
    int nwrote, 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);
        nwrote = size - nleft;
        if (nwrote > 0)
            return (nwrote);
        errno = ETIMEDOUT;
        return (kTimeoutErr);
    }

    if (SSetjmp(gPipeJmp) != 0) {
        alarm(0);
        (void) SSignal(SIGALRM, (sio_sigproc_t) sigalrm);
        (void) SSignal(SIGPIPE, (sio_sigproc_t) sigpipe);
        nwrote = size - nleft;
        if (nwrote > 0)
            return (nwrote);
        errno = EPIPE;
        return (kBrokenPipeErr);
    }

    sigalrm = (vsio_sigproc_t) SSignal(SIGALRM, SIOHandler);
    sigpipe = (vsio_sigproc_t) SSignal(SIGPIPE, SIOHandler);

    nleft = (int) size;
    time(&now);
    done = now + tlen;
    forever {
        tleft = (int) (done - now);
        if (tleft < 1) {
            nwrote = size - nleft;
            if (nwrote == 0) {
                nwrote = kTimeoutErr;
                errno = ETIMEDOUT;
            }
            goto done;
        }
        (void) alarm((unsigned int) tleft);
        nwrote = write(sfd, buf, nleft);
        (void) alarm(0);
        if (nwrote < 0) {
            if (errno != EINTR) {
                nwrote = size - nleft;
                if (nwrote == 0)
                    nwrote = -1;
                goto done;
            } else {
                errno = 0;
                nwrote = 0;
                /* Try again. */
            }
        }
        nleft -= nwrote;
        if (nleft <= 0)
            break;
        buf += nwrote;
        time(&now);
    }
    nwrote = size - nleft;

done:
    (void) SSignal(SIGALRM, (sio_sigproc_t) sigalrm);
    (void) SSignal(SIGPIPE, (sio_sigproc_t) sigpipe);

    return (nwrote);
}	/* SWrite */
Ejemplo n.º 7
0
int
SRecv(int sfd, char *const buf0, size_t size, int fl, int tlen, int retry)
{
	int nread;
	volatile int nleft;
	char *volatile buf = buf0;
	int 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);
		nread = size - nleft;
		if ((nread > 0) && (retry == kFullBufferNotRequired))
			return (nread);
		errno = ETIMEDOUT;
		return (kTimeoutErr);
	}

	if (SSetjmp(gPipeJmp) != 0) {
		alarm(0);
		(void) SSignal(SIGALRM, (sio_sigproc_t) sigalrm);
		(void) SSignal(SIGPIPE, (sio_sigproc_t) sigpipe);
		nread = size - nleft;
		if ((nread > 0) && (retry == kFullBufferNotRequired))
			return (nread);
		errno = EPIPE;
		return (kBrokenPipeErr);
	}

	sigalrm = (vsio_sigproc_t) SSignal(SIGALRM, SIOHandler);
	sigpipe = (vsio_sigproc_t) SSignal(SIGPIPE, SIOHandler);
	errno = 0;

	nleft = (int) size;
	time(&now);
	done = now + tlen;
	forever {
		tleft = (int) (done - now);
		if (tleft < 1) {
			nread = size - nleft;
			if ((nread == 0) || (retry == kFullBufferRequired)) {
				nread = kTimeoutErr;
				errno = ETIMEDOUT;
			}
			goto done;
		}
		(void) alarm((unsigned int) tleft);
		nread = recv(sfd, (char *) buf, nleft, fl);
		(void) alarm(0);
		if (nread <= 0) {
			if (nread == 0) {
				/* EOF */
				if (retry == kFullBufferRequiredExceptLast)
					nread = size - nleft;
				goto done;
			} else if (errno != EINTR) {
				nread = size - nleft;
				if (nread == 0)
					nread = -1;
				goto done;
			} else {
				errno = 0;
				nread = 0;
				/* Try again. */
			}
		}
		nleft -= nread;
		if ((nleft <= 0) || ((retry == 0) && (nleft != (int) size)))
			break;
		buf += nread;
		time(&now);
	}
	nread = size - nleft;

done:
	(void) SSignal(SIGALRM, (sio_sigproc_t) sigalrm);
	(void) SSignal(SIGPIPE, (sio_sigproc_t) sigpipe);

	return (nread);
}	/* SRecv */
Ejemplo n.º 8
0
int
SClose(int sfd, int tlen)
{
#ifdef UNIX_SIGNALS
	volatile sio_sigproc_t sigalrm = (sio_sigproc_t) 0;
	volatile sio_sigproc_t sigpipe = (sio_sigproc_t) 0;
	volatile alarm_time_t oalarm = 0;
	int result;
	int oerrno;
	
	if (sfd < 0) {
		errno = EBADF;
		return (-1);
	}

	if (GetSocketLinger(sfd, NULL) <= 0) {
		/* Linger wasn't on, so close shouldn't block.
		 * Take the regular way out.
		 */
		return (SCloseSocket(sfd));
	}
	
	if (tlen < 1) {
		/* Don't time it, shut it down now. */
		if (SetSocketLinger(sfd, 0, 0) == 0) {
			/* Linger disabled, so close()
			 * should not block.
			 */
			return (SCloseSocket(sfd));
		} else {
			/* This may result in a fd leak,
			 * but it's either that or hang forever.
			 */
			(void) shutdown(sfd, 2);
			return (SCloseSocket(sfd));
		}
	}

	if (SSetjmp(gNetTimeoutJmp) != 0) {
		(void) alarm(0);
		(void) SetSocketLinger(sfd, 0, 0);
		errno = 0;
		(void) shutdown(sfd, 2);
		result = closesocket(sfd);
		oerrno = errno;
		(void) SSignal(SIGALRM, (sio_sigproc_t) sigalrm);
		(void) SSignal(SIGPIPE, (sio_sigproc_t) sigpipe);
		(void) alarm(oalarm);
		errno = oerrno;
		return (result);
	}

	sigalrm = (sio_sigproc_t) SSignal(SIGALRM, SIOHandler);
	sigpipe = (sio_sigproc_t) SSignal(SIGPIPE, SIG_IGN);

	oalarm = alarm((alarm_time_t) tlen);
	for (errno = 0;;) {
		result = closesocket(sfd);
		if (result == 0)
			break;
		if (errno != EINTR)
			break;
	}
	oerrno = errno;
	(void) alarm(0);

	if ((result != 0) && (errno != EBADF)) {
		(void) SetSocketLinger(sfd, 0, 0);
		(void) shutdown(sfd, 2);
		result = closesocket(sfd);
		oerrno = errno;
	}
	
	(void) SSignal(SIGALRM, (sio_sigproc_t) sigalrm);
	(void) SSignal(SIGPIPE, (sio_sigproc_t) sigpipe);
	(void) alarm(oalarm);
	errno = oerrno;
	
	return (result);
#else	/* ! UNIX_SIGNALS */
	if (sfd < 0) {
		errno = EBADF;
		return (-1);
	}
	
	/* Sorry... it's up to you to make sure you don't block forever
	 * on closesocket() since this platform doesn't have alarm().
	 * Even so, it shouldn't be a problem unless you use linger mode
	 * on the socket, and nobody does that these days.
	 */
	return (SCloseSocket(sfd));
#endif
}	/* SClose */