Init
This commit is contained in:
189
lib/libsocket/socket/_conn_util.c
Executable file
189
lib/libsocket/socket/_conn_util.c
Executable file
@@ -0,0 +1,189 @@
|
||||
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
|
||||
/* All Rights Reserved */
|
||||
|
||||
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
|
||||
/* The copyright notice above does not evidence any */
|
||||
/* actual or intended publication of such source code. */
|
||||
|
||||
#ident "@(#)_conn_util.c 1.11 93/09/30 SMI" /* SVr4.0 1.6 */
|
||||
/*
|
||||
* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
* PROPRIETARY NOTICE (Combined)
|
||||
*
|
||||
* This source code is unpublished proprietary information
|
||||
* constituting, or derived under license from AT&T's UNIX(r) System V.
|
||||
* In addition, portions of such source code were derived from Berkeley
|
||||
* 4.3 BSD under license from the Regents of the University of
|
||||
* California.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Copyright Notice
|
||||
*
|
||||
* Notice of copyright on this source code product does not indicate
|
||||
* publication.
|
||||
*
|
||||
* (c) 1986-1992 Sun Microsystems, Inc
|
||||
* (c) 1983,1984,1985,1986,1987,1988,1989 AT&T.
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "sockmt.h"
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stream.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <stropts.h>
|
||||
#include <sys/tihdr.h>
|
||||
#include <sys/socket.h>
|
||||
#include <tiuser.h>
|
||||
#include <sys/sockmod.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "sock.h"
|
||||
|
||||
|
||||
/*
|
||||
* Snd_conn_req - send connect request message to
|
||||
* transport provider
|
||||
*/
|
||||
int
|
||||
_s_snd_conn_req(siptr, call, ctlbufp)
|
||||
register struct _si_user *siptr;
|
||||
register struct t_call *call;
|
||||
struct strbuf *ctlbufp;
|
||||
{
|
||||
register struct T_conn_req *creq;
|
||||
register char *buf;
|
||||
register int size;
|
||||
|
||||
buf = ctlbufp->buf;
|
||||
creq = (struct T_conn_req *)buf;
|
||||
creq->PRIM_type = T_CONN_REQ;
|
||||
creq->DEST_length = call->addr.len;
|
||||
creq->DEST_offset = 0;
|
||||
creq->OPT_length = call->opt.len;
|
||||
creq->OPT_offset = 0;
|
||||
size = sizeof (struct T_conn_req);
|
||||
|
||||
if (call->addr.len) {
|
||||
_s_aligned_copy(buf, call->addr.len, size,
|
||||
call->addr.buf, (int *)&creq->DEST_offset);
|
||||
size = creq->DEST_offset + creq->DEST_length;
|
||||
}
|
||||
if (call->opt.len && call->opt.len != -1) {
|
||||
_s_aligned_copy(buf, call->opt.len, size,
|
||||
call->opt.buf, (int *)&creq->OPT_offset);
|
||||
size = creq->OPT_offset + creq->OPT_length;
|
||||
}
|
||||
|
||||
ctlbufp->len = size;
|
||||
|
||||
if (putmsg(siptr->fd, ctlbufp,
|
||||
(struct strbuf *)(call->udata.len? &call->udata: NULL), 0) < 0)
|
||||
return (-1);
|
||||
|
||||
if (!_s_is_ok(siptr, T_CONN_REQ, ctlbufp))
|
||||
return (-1);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Rcv_conn_con - get connection confirmation off
|
||||
* of read queue
|
||||
*/
|
||||
int
|
||||
_s_rcv_conn_con(siptr, ctlbufp)
|
||||
register struct _si_user *siptr;
|
||||
struct strbuf *ctlbufp;
|
||||
{
|
||||
struct strbuf databuf;
|
||||
register union T_primitives *pptr;
|
||||
register int retval;
|
||||
int flg;
|
||||
char dbuf[256];
|
||||
|
||||
flg = 0;
|
||||
if (siptr->udata.servtype == T_CLTS) {
|
||||
errno = EOPNOTSUPP;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
ctlbufp->len = 0;
|
||||
|
||||
databuf.maxlen = sizeof (dbuf);
|
||||
databuf.len = 0;
|
||||
databuf.buf = dbuf;
|
||||
|
||||
/*
|
||||
* No data expected for TCP, but we read and discard data for
|
||||
* other transport providers.
|
||||
*/
|
||||
if ((retval = getmsg(siptr->fd, ctlbufp, &databuf, &flg)) < 0) {
|
||||
if (errno == ENXIO)
|
||||
errno = ECONNREFUSED;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* did we get entire control message
|
||||
*/
|
||||
if (retval & MORECTL) {
|
||||
/* more control part is unexpected */
|
||||
errno = EIO;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
while (retval & MOREDATA) {
|
||||
/*
|
||||
* More connect data is present.
|
||||
* We try to read it all and discard it.
|
||||
*/
|
||||
if ((retval = getmsg(siptr->fd, NULL, &databuf, &flg)) < 0) {
|
||||
if (errno == ENXIO)
|
||||
errno = ECONNREFUSED;
|
||||
return (-1);
|
||||
}
|
||||
if (retval & MORECTL) {
|
||||
/*
|
||||
* Error if any control part on stream head
|
||||
* while remaining user data is being retrieved.
|
||||
* ??Can also happen if any higher priority message
|
||||
* is recived??
|
||||
*/
|
||||
errno = EIO;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* is cntl part large enough to determine message type?
|
||||
*/
|
||||
if (ctlbufp->len < sizeof (long)) {
|
||||
errno = EPROTO;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
pptr = (union T_primitives *)ctlbufp->buf;
|
||||
switch (pptr->type) {
|
||||
case T_CONN_CON:
|
||||
return (0);
|
||||
|
||||
case T_DISCON_IND:
|
||||
if (ctlbufp->len < sizeof (struct T_discon_ind))
|
||||
errno = ECONNREFUSED;
|
||||
else errno = pptr->discon_ind.DISCON_reason;
|
||||
return (-1);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
errno = EPROTO;
|
||||
return (-1);
|
||||
}
|
||||
2050
lib/libsocket/socket/_utility.c
Executable file
2050
lib/libsocket/socket/_utility.c
Executable file
File diff suppressed because it is too large
Load Diff
378
lib/libsocket/socket/accept.c
Executable file
378
lib/libsocket/socket/accept.c
Executable file
@@ -0,0 +1,378 @@
|
||||
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
|
||||
/* All Rights Reserved */
|
||||
|
||||
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
|
||||
/* The copyright notice above does not evidence any */
|
||||
/* actual or intended publication of such source code. */
|
||||
|
||||
#ident "@(#)accept.c 1.19 94/08/17 SMI" /* SVr4.0 1.12 */
|
||||
|
||||
/*
|
||||
* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
* PROPRIETARY NOTICE (Combined)
|
||||
*
|
||||
* This source code is unpublished proprietary information
|
||||
* constituting, or derived under license from AT&T's UNIX(r) System V.
|
||||
* In addition, portions of such source code were derived from Berkeley
|
||||
* 4.3 BSD under license from the Regents of the University of
|
||||
* California.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Copyright Notice
|
||||
*
|
||||
* Notice of copyright on this source code product does not indicate
|
||||
* publication.
|
||||
*
|
||||
* (c) 1986,1987,1988.1989 Sun Microsystems, Inc
|
||||
* (c) 1983,1984,1985,1986,1987,1988,1989 AT&T.
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "sockmt.h"
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/mkdev.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stream.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <stropts.h>
|
||||
#include <sys/tihdr.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/socket.h>
|
||||
#include <tiuser.h>
|
||||
#include <signal.h>
|
||||
#include <sys/sockmod.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <fcntl.h>
|
||||
#include <syslog.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "sock.h"
|
||||
|
||||
#pragma weak accept = _accept
|
||||
|
||||
static void _so_disconnect(struct _si_user *siptr, int seqno,
|
||||
struct strbuf *ctlbufp);
|
||||
|
||||
int
|
||||
_accept(s, addr, addrlen)
|
||||
register int s;
|
||||
register struct sockaddr *addr;
|
||||
register int *addrlen;
|
||||
|
||||
{
|
||||
register struct _si_user *siptr;
|
||||
sigset_t mask;
|
||||
int retval;
|
||||
|
||||
if ((siptr = _s_checkfd(s)) == NULL)
|
||||
return (-1);
|
||||
|
||||
MUTEX_LOCK_SIGMASK(&siptr->lock, mask);
|
||||
if (siptr->udata.servtype == T_CLTS) {
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
errno = EOPNOTSUPP;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure a listen() has been done
|
||||
* actually if the accept() has not been done, then the
|
||||
* effect will be that the user blocks forever.
|
||||
*/
|
||||
if ((siptr->udata.so_options & SO_ACCEPTCONN) == 0) {
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
retval = __accept(siptr, addr, addrlen, &mask);
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
return (retval);
|
||||
}
|
||||
|
||||
int
|
||||
__accept(siptr, addr, addrlen, accmaskp)
|
||||
register struct _si_user *siptr;
|
||||
register struct sockaddr *addr;
|
||||
register int *addrlen;
|
||||
sigset_t *accmaskp;
|
||||
{
|
||||
|
||||
register struct T_conn_res *cres;
|
||||
register struct _si_user *nsiptr;
|
||||
register int s;
|
||||
register int s2;
|
||||
int retval;
|
||||
register union T_primitives *pptr;
|
||||
struct strfdinsert strfdinsert;
|
||||
int flg;
|
||||
struct strbuf ctlbuf;
|
||||
struct strbuf databuf;
|
||||
char dbuf[256];
|
||||
sigset_t mask;
|
||||
sigset_t procmask;
|
||||
int didalloc = 0;
|
||||
|
||||
flg = 0;
|
||||
s = siptr->fd;
|
||||
|
||||
/*
|
||||
* Get/wait for the T_CONN_IND.
|
||||
*/
|
||||
ctlbuf.len = 0;
|
||||
if (siptr->ctlbuf) {
|
||||
ctlbuf.buf = siptr->ctlbuf;
|
||||
siptr->ctlbuf = NULL;
|
||||
ctlbuf.maxlen = siptr->ctlsize;
|
||||
} else {
|
||||
/*
|
||||
* siptr->ctlbuf is in use
|
||||
* allocate and free after use.
|
||||
*/
|
||||
if ((ctlbuf.maxlen = _s_cbuf_alloc(siptr,
|
||||
&ctlbuf.buf)) < 0)
|
||||
return (-1);
|
||||
didalloc = 1;
|
||||
}
|
||||
|
||||
databuf.maxlen = sizeof (dbuf);
|
||||
databuf.len = 0;
|
||||
databuf.buf = dbuf;
|
||||
/*
|
||||
* User data read and discarded for transport providers that
|
||||
* use connect data.
|
||||
* This is a call that may block indeinitely so we drop the lock and
|
||||
* allow signals in MT case here and reacquire it.
|
||||
*/
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, *accmaskp);
|
||||
if ((retval = getmsg(s, &ctlbuf, &databuf, &flg)) < 0) {
|
||||
MUTEX_LOCK_SIGMASK(&siptr->lock, *accmaskp);
|
||||
goto err_out;
|
||||
}
|
||||
MUTEX_LOCK_SIGMASK(&siptr->lock, *accmaskp);
|
||||
/*
|
||||
* did I get entire control message?
|
||||
*/
|
||||
if (retval & MORECTL) {
|
||||
errno = EIO;
|
||||
goto err_out;
|
||||
}
|
||||
/*
|
||||
* We recieved a T_CONN_IND. We are commited to it and
|
||||
* do not want to fail with EINTR which may result in lost
|
||||
* connection requests
|
||||
*/
|
||||
_s_blockallsignals(&procmask);
|
||||
while (retval & MOREDATA) {
|
||||
/*
|
||||
* More connect data is present.
|
||||
* We try to read it all and discard it.
|
||||
*/
|
||||
if ((retval = getmsg(siptr->fd, NULL, &databuf, &flg)) < 0) {
|
||||
int saved_errno = errno;
|
||||
_s_restoresigmask(&procmask);
|
||||
errno = saved_errno;
|
||||
goto err_out;
|
||||
}
|
||||
if (retval & MORECTL) {
|
||||
/*
|
||||
* Error if any control part on stream head
|
||||
* while remaining user data is being retrieved.
|
||||
* ??Can also happen if any higher priority message
|
||||
* is recived??
|
||||
*/
|
||||
_s_restoresigmask(&procmask);
|
||||
errno = EIO;
|
||||
goto err_out;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* is ctl part large enough to determine type
|
||||
*/
|
||||
if (ctlbuf.len < sizeof (long)) {
|
||||
_s_restoresigmask(&procmask);
|
||||
errno = EPROTO;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
pptr = (union T_primitives *)ctlbuf.buf;
|
||||
switch (pptr->type) {
|
||||
case T_CONN_IND:
|
||||
if (ctlbuf.len < (sizeof (struct T_conn_ind)+
|
||||
pptr->conn_ind.SRC_length)) {
|
||||
_s_restoresigmask(&procmask);
|
||||
errno = EPROTO;
|
||||
goto err_out;
|
||||
}
|
||||
if (addr && addrlen) {
|
||||
*addrlen = _s_cpaddr(siptr, (char *)addr,
|
||||
*addrlen,
|
||||
ctlbuf.buf + pptr->conn_ind.SRC_offset,
|
||||
pptr->conn_ind.SRC_length);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
_s_restoresigmask(&procmask);
|
||||
errno = EPROTO;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Open a new instance to do the accept on
|
||||
*
|
||||
*/
|
||||
if ((nsiptr = _s_socreate(siptr->udata.sockparams.sp_family,
|
||||
siptr->udata.sockparams.sp_type,
|
||||
siptr->udata.sockparams.sp_protocol))
|
||||
== NULL) {
|
||||
int saved_errno = errno;
|
||||
|
||||
_so_disconnect(siptr, pptr->conn_ind.SEQ_number, &ctlbuf);
|
||||
_s_restoresigmask(&procmask);
|
||||
errno = saved_errno;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
s2 = nsiptr->fd;
|
||||
|
||||
MUTEX_LOCK_SIGMASK(&nsiptr->lock, mask);
|
||||
/*
|
||||
* must be bound for TLI except TCP.
|
||||
*/
|
||||
if (nsiptr->udata.sockparams.sp_family == AF_INET &&
|
||||
nsiptr->udata.sockparams.sp_type == SOCK_STREAM) {
|
||||
nsiptr->udata.so_state |= SS_ISBOUND;
|
||||
} else if (__bind(nsiptr, NULL, 0, NULL, NULL) < 0) {
|
||||
int saved_errno = errno;
|
||||
|
||||
MUTEX_UNLOCK_SIGMASK(&nsiptr->lock, mask);
|
||||
_s_close(nsiptr);
|
||||
_so_disconnect(siptr, pptr->conn_ind.SEQ_number, &ctlbuf);
|
||||
_s_restoresigmask(&procmask);
|
||||
errno = saved_errno;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
cres = (struct T_conn_res *) ctlbuf.buf;
|
||||
cres->PRIM_type = T_CONN_RES;
|
||||
cres->OPT_length = 0;
|
||||
cres->OPT_offset = 0;
|
||||
cres->SEQ_number = pptr->conn_ind.SEQ_number;
|
||||
|
||||
strfdinsert.ctlbuf.maxlen = ctlbuf.maxlen;
|
||||
strfdinsert.ctlbuf.len = sizeof (*cres);
|
||||
strfdinsert.ctlbuf.buf = (caddr_t)cres;
|
||||
|
||||
strfdinsert.databuf.maxlen = 0;
|
||||
strfdinsert.databuf.len = -1;
|
||||
strfdinsert.databuf.buf = NULL;
|
||||
|
||||
strfdinsert.fildes = s2;
|
||||
strfdinsert.offset = sizeof (long);
|
||||
strfdinsert.flags = 0;
|
||||
|
||||
if (_ioctl(s, I_FDINSERT, &strfdinsert) < 0) {
|
||||
int saved_errno = errno;
|
||||
MUTEX_UNLOCK_SIGMASK(&nsiptr->lock, mask);
|
||||
_s_close(nsiptr);
|
||||
errno = saved_errno;
|
||||
_s_restoresigmask(&procmask);
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
if (!_s_is_ok(siptr, T_CONN_RES, &ctlbuf)) {
|
||||
int saved_errno = errno;
|
||||
MUTEX_UNLOCK_SIGMASK(&nsiptr->lock, mask);
|
||||
_s_close(nsiptr);
|
||||
_s_restoresigmask(&procmask);
|
||||
errno = saved_errno;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
/*
|
||||
* New socket must have attributes of the
|
||||
* accepting socket.
|
||||
*/
|
||||
nsiptr->udata.so_state |= SS_ISCONNECTED;
|
||||
nsiptr->udata.so_options = siptr->udata.so_options & ~SO_ACCEPTCONN;
|
||||
MUTEX_UNLOCK_SIGMASK(&nsiptr->lock, mask);
|
||||
|
||||
_s_restoresigmask(&procmask);
|
||||
|
||||
/*
|
||||
* Make the ownership of the new socket the
|
||||
* same as the original.
|
||||
*/
|
||||
if (siptr->flags & (S_SIGIO|S_SIGURG)) {
|
||||
retval = 0;
|
||||
|
||||
if (s_ioctl(s, SIOCGPGRP, &retval) == 0) {
|
||||
if (retval != 0) {
|
||||
(void) s_ioctl(nsiptr->fd, SIOCSPGRP, &retval);
|
||||
}
|
||||
} else {
|
||||
(void) syslog(LOG_ERR,
|
||||
"accept: SIOCGPGRP failed errno %d\n",
|
||||
errno);
|
||||
errno = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The accepted socket inherits the non-blocking and SIGIO
|
||||
* attributes of the accepting socket.
|
||||
*/
|
||||
flg = s_getfflags(siptr);
|
||||
/*
|
||||
* fcntl(F_GETFL) (but not _fcntl) sets FASYNC when S_SIGIO is
|
||||
* set. We do the same thing here. The fcntl(F_SETFL) will handle
|
||||
* the FASYNC flag by doing the I_SETSIG etc.
|
||||
* XXX Note: s_fcntl called directly instead of fcntl till
|
||||
* linking problems when calling with BCP or search paths with
|
||||
* libc ahead of libsocket are fixed.
|
||||
*/
|
||||
if (siptr->flags & S_SIGIO)
|
||||
flg |= FASYNC;
|
||||
if (flg & (FASYNC|FNDELAY|FNONBLOCK)) {
|
||||
flg &= (FREAD|FWRITE|FASYNC|FNDELAY|FNONBLOCK);
|
||||
(void) s_fcntl(nsiptr->fd, F_SETFL, flg);
|
||||
}
|
||||
if (didalloc)
|
||||
free(ctlbuf.buf);
|
||||
else
|
||||
siptr->ctlbuf = ctlbuf.buf;
|
||||
|
||||
return (s2);
|
||||
|
||||
err_out:
|
||||
if (didalloc)
|
||||
free(ctlbuf.buf);
|
||||
else
|
||||
siptr->ctlbuf = ctlbuf.buf;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Must be called holding the mutex on siptr
|
||||
*/
|
||||
static void
|
||||
_so_disconnect(struct _si_user *siptr, int seqno, struct strbuf *ctlbufp)
|
||||
{
|
||||
register struct T_discon_req *dreq;
|
||||
|
||||
ctlbufp->len = sizeof (*dreq);
|
||||
|
||||
dreq = (struct T_discon_req *) ctlbufp->buf;
|
||||
dreq->PRIM_type = T_DISCON_REQ;
|
||||
dreq->SEQ_number = seqno;
|
||||
|
||||
(void) putmsg(siptr->fd, ctlbufp, NULL, 0);
|
||||
}
|
||||
361
lib/libsocket/socket/bind.c
Executable file
361
lib/libsocket/socket/bind.c
Executable file
@@ -0,0 +1,361 @@
|
||||
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
|
||||
/* All Rights Reserved */
|
||||
|
||||
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
|
||||
/* The copyright notice above does not evidence any */
|
||||
/* actual or intended publication of such source code. */
|
||||
|
||||
#ident "@(#)bind.c 1.20 95/07/12 SMI" /* SVr4.0 1.9 */
|
||||
|
||||
/*
|
||||
* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
* PROPRIETARY NOTICE (Combined)
|
||||
*
|
||||
* This source code is unpublished proprietary information
|
||||
* constituting, or derived under license from AT&T's UNIX(r) System V.
|
||||
* In addition, portions of such source code were derived from Berkeley
|
||||
* 4.3 BSD under license from the Regents of the University of
|
||||
* California.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Copyright Notice
|
||||
*
|
||||
* Notice of copyright on this source code product does not indicate
|
||||
* publication.
|
||||
*
|
||||
* (c) 1986,1987,1988.1989 Sun Microsystems, Inc
|
||||
* (c) 1983,1984,1985,1986,1987,1988,1989 AT&T.
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "sockmt.h"
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stream.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <stropts.h>
|
||||
#include <sys/tihdr.h>
|
||||
#include <sys/timod.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/socket.h>
|
||||
#include <tiuser.h>
|
||||
#include <sys/sockmod.h>
|
||||
#include <signal.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/stat.h>
|
||||
#include <syslog.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "sock.h"
|
||||
|
||||
static int _unbind(struct _si_user *siptr);
|
||||
|
||||
#pragma weak bind = _bind
|
||||
|
||||
int
|
||||
_bind(s, name, namelen)
|
||||
register int s;
|
||||
register struct sockaddr *name;
|
||||
register int namelen;
|
||||
{
|
||||
register struct _si_user *siptr;
|
||||
sigset_t mask;
|
||||
int retval;
|
||||
u_int family;
|
||||
|
||||
if ((siptr = _s_checkfd(s)) == NULL)
|
||||
return (-1);
|
||||
|
||||
MUTEX_LOCK_SIGMASK(&siptr->lock, mask);
|
||||
if (name == NULL || namelen == 0) {
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (siptr->udata.so_state & SS_ISBOUND) {
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
family = name->sa_family;
|
||||
if (family == 0) {
|
||||
/*
|
||||
* Handle old applications that do not set the family
|
||||
* in the bind call.
|
||||
*/
|
||||
family = siptr->udata.sockparams.sp_family;
|
||||
name->sa_family = family;
|
||||
}
|
||||
/*
|
||||
* In UNIX domain a bind address must be given.
|
||||
*/
|
||||
if (family == AF_UNIX) {
|
||||
if (namelen <= sizeof (name->sa_family)) {
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
errno = EISDIR;
|
||||
return (-1);
|
||||
}
|
||||
if (namelen > sizeof (struct sockaddr_un)) {
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
if (name->sa_data[0] == 0) {
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
retval = __bind(siptr, name, namelen, NULL, NULL);
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
return (retval);
|
||||
}
|
||||
|
||||
int
|
||||
__bind(siptr, name, namelen, raddr, raddrlen)
|
||||
register struct _si_user *siptr;
|
||||
register struct sockaddr *name;
|
||||
register int namelen;
|
||||
register char *raddr;
|
||||
register int *raddrlen;
|
||||
{
|
||||
register char *buf;
|
||||
register struct T_bind_req *bind_req;
|
||||
register struct T_bind_ack *bind_ack;
|
||||
register int size;
|
||||
char *cbuf;
|
||||
sigset_t procmask;
|
||||
struct stat rstat;
|
||||
struct bind_ux bind_ux;
|
||||
int fflag;
|
||||
int didalloc = 0;
|
||||
|
||||
if (siptr->udata.sockparams.sp_family == AF_UNIX) {
|
||||
(void) memset((caddr_t)&bind_ux, 0, sizeof (bind_ux));
|
||||
|
||||
if (name == NULL) {
|
||||
bind_ux.name.sun_family = AF_UNIX;
|
||||
fflag = 0;
|
||||
} else {
|
||||
struct sockaddr_un *un;
|
||||
int len;
|
||||
|
||||
un = (struct sockaddr_un *)name;
|
||||
|
||||
if (un->sun_family != AF_UNIX) {
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
if (namelen > sizeof (*un) ||
|
||||
(len = _s_uxpathlen(un)) ==
|
||||
sizeof (un->sun_path)) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
un->sun_path[len] = 0; /* Null terminate */
|
||||
|
||||
/*
|
||||
* We really have to bind to the actual vnode, so
|
||||
* that renames will not cause a problem. First
|
||||
* create the file and then get the dev/ino to
|
||||
* bind to.
|
||||
*/
|
||||
if ((_ioctl(siptr->fd, _I_BIND_RSVD, un->sun_path) < 0) ||
|
||||
#if defined(i386)
|
||||
(_xstat(_STAT_VER, (caddr_t) un->sun_path,
|
||||
&rstat) < 0)) {
|
||||
#elif defined(sparc)
|
||||
_stat((caddr_t)un->sun_path, &rstat) < 0) {
|
||||
#else
|
||||
#error Unknown architecture!
|
||||
#endif
|
||||
if (errno == EEXIST)
|
||||
errno = EADDRINUSE;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
bind_ux.extdev = rstat.st_dev;
|
||||
bind_ux.extino = rstat.st_ino;
|
||||
bind_ux.extsize = sizeof (struct ux_dev);
|
||||
|
||||
(void) memcpy((caddr_t)&bind_ux.name, (caddr_t)name,
|
||||
namelen);
|
||||
fflag = 1;
|
||||
}
|
||||
name = (struct sockaddr *)&bind_ux;
|
||||
namelen = sizeof (bind_ux);
|
||||
} else namelen = _s_min(namelen, siptr->udata.addrsize);
|
||||
|
||||
if (siptr->ctlbuf) {
|
||||
cbuf = siptr->ctlbuf;
|
||||
siptr->ctlbuf = NULL;
|
||||
} else {
|
||||
/*
|
||||
* siptr->ctlbuf is in use
|
||||
* allocate and free after use.
|
||||
*/
|
||||
if (_s_cbuf_alloc(siptr, &cbuf) < 0)
|
||||
return (-1);
|
||||
didalloc = 1;
|
||||
}
|
||||
buf = cbuf;
|
||||
bind_req = (struct T_bind_req *)buf;
|
||||
size = sizeof (*bind_req);
|
||||
|
||||
bind_req->PRIM_type = T_BIND_REQ;
|
||||
bind_req->ADDR_length = name == NULL ? 0 : namelen;
|
||||
bind_req->ADDR_offset = 0;
|
||||
bind_req->CONIND_number = 0;
|
||||
|
||||
if (bind_req->ADDR_length) {
|
||||
_s_aligned_copy(buf, bind_req->ADDR_length, size,
|
||||
(caddr_t)name,
|
||||
(int *)&bind_req->ADDR_offset);
|
||||
size = bind_req->ADDR_offset + bind_req->ADDR_length;
|
||||
}
|
||||
|
||||
_s_blockallsignals(&procmask);
|
||||
if (!_s_do_ioctl(siptr->fd, buf, size, TI_BIND, NULL)) {
|
||||
_s_restoresigmask(&procmask);
|
||||
goto err_out;
|
||||
}
|
||||
_s_restoresigmask(&procmask);
|
||||
|
||||
bind_ack = (struct T_bind_ack *)buf;
|
||||
buf += bind_ack->ADDR_offset;
|
||||
|
||||
/*
|
||||
* Check that the address returned by the
|
||||
* transport provider meets the criteria.
|
||||
*/
|
||||
errno = 0;
|
||||
if (name != (struct sockaddr *)NULL) {
|
||||
/*
|
||||
* Some programs like inetd(1M) don't set the
|
||||
* family field. So we use the family field that
|
||||
* was passed in to the socket() call.
|
||||
*/
|
||||
switch (siptr->udata.sockparams.sp_family) {
|
||||
case AF_INET: {
|
||||
struct sockaddr_in *rname;
|
||||
struct sockaddr_in *aname;
|
||||
|
||||
rname = (struct sockaddr_in *)buf;
|
||||
aname = (struct sockaddr_in *)name;
|
||||
|
||||
if (aname->sin_port != 0 &&
|
||||
aname->sin_port != rname->sin_port)
|
||||
errno = EADDRINUSE;
|
||||
|
||||
if (aname->sin_addr.s_addr != INADDR_ANY &&
|
||||
aname->sin_addr.s_addr != rname->sin_addr.s_addr)
|
||||
errno = EADDRNOTAVAIL;
|
||||
break;
|
||||
}
|
||||
|
||||
case AF_UNIX:
|
||||
if (fflag) {
|
||||
|
||||
register struct bind_ux *rbind_ux;
|
||||
rbind_ux = (struct bind_ux *)buf;
|
||||
if (rbind_ux->extdev != bind_ux.extdev ||
|
||||
rbind_ux->extino != bind_ux.extino)
|
||||
errno = EADDRINUSE;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (bind_ack->ADDR_length != namelen)
|
||||
errno = EADDRNOTAVAIL;
|
||||
else if (memcmp((caddr_t)name, buf, namelen) != 0)
|
||||
errno = EADDRNOTAVAIL;
|
||||
}
|
||||
}
|
||||
|
||||
if (errno) {
|
||||
register int error;
|
||||
|
||||
error = errno; /* Save it */
|
||||
(void) _unbind(siptr);
|
||||
if (name && name->sa_family == AF_UNIX && fflag) {
|
||||
(void) _ioctl(siptr->fd, _I_RELE_RSVD);
|
||||
(void) unlink(name->sa_data);
|
||||
}
|
||||
errno = error;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy back the bound address if requested.
|
||||
*/
|
||||
if (raddr != NULL)
|
||||
*raddrlen = _s_cpaddr(siptr, raddr, *raddrlen,
|
||||
buf, bind_ack->ADDR_length);
|
||||
|
||||
siptr->udata.so_state |= SS_ISBOUND;
|
||||
|
||||
if (didalloc)
|
||||
free(cbuf);
|
||||
else
|
||||
siptr->ctlbuf = cbuf;
|
||||
|
||||
return (0);
|
||||
|
||||
err_out:
|
||||
if (didalloc)
|
||||
free(cbuf);
|
||||
else
|
||||
siptr->ctlbuf = cbuf;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static int
|
||||
_unbind(siptr)
|
||||
register struct _si_user *siptr;
|
||||
{
|
||||
sigset_t procmask;
|
||||
char *cbuf;
|
||||
int didalloc = 0;
|
||||
|
||||
if (siptr->ctlbuf) {
|
||||
cbuf = siptr->ctlbuf;
|
||||
siptr->ctlbuf = NULL;
|
||||
} else {
|
||||
/*
|
||||
* siptr->ctlbuf is in use
|
||||
* allocate and free after use.
|
||||
*/
|
||||
if (_s_cbuf_alloc(siptr, &cbuf) < 0)
|
||||
return (-1);
|
||||
didalloc = 1;
|
||||
}
|
||||
|
||||
((struct T_unbind_req *)cbuf)->PRIM_type = T_UNBIND_REQ;
|
||||
|
||||
_s_blockallsignals(&procmask);
|
||||
if (!_s_do_ioctl(siptr->fd, cbuf,
|
||||
sizeof (struct T_unbind_req),
|
||||
TI_UNBIND, NULL)) {
|
||||
_s_restoresigmask(&procmask);
|
||||
if (didalloc)
|
||||
free(cbuf);
|
||||
else
|
||||
siptr->ctlbuf = cbuf;
|
||||
return (-1);
|
||||
}
|
||||
_s_restoresigmask(&procmask);
|
||||
|
||||
siptr->udata.so_state &= ~SS_ISBOUND;
|
||||
if (didalloc)
|
||||
free(cbuf);
|
||||
else
|
||||
siptr->ctlbuf = cbuf;
|
||||
return (0);
|
||||
}
|
||||
16
lib/libsocket/socket/callselect.c
Executable file
16
lib/libsocket/socket/callselect.c
Executable file
@@ -0,0 +1,16 @@
|
||||
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
|
||||
/* All Rights Reserved */
|
||||
|
||||
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
|
||||
/* The copyright notice above does not evidence any */
|
||||
/* actual or intended publication of such source code. */
|
||||
|
||||
#ident "@(#)callselect.c 1.3 93/09/30 SMI" /* SVr4.0 1.1 */
|
||||
|
||||
/*
|
||||
* dummy routine to force select() to be linked from archive libc
|
||||
*/
|
||||
callselect()
|
||||
{
|
||||
select(0, 0, 0, 0, 0);
|
||||
}
|
||||
276
lib/libsocket/socket/connect.c
Executable file
276
lib/libsocket/socket/connect.c
Executable file
@@ -0,0 +1,276 @@
|
||||
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
|
||||
/* All Rights Reserved */
|
||||
|
||||
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
|
||||
/* The copyright notice above does not evidence any */
|
||||
/* actual or intended publication of such source code. */
|
||||
|
||||
#ident "@(#)connect.c 1.16 94/04/08 SMI" /* SVr4.0 1.7 */
|
||||
|
||||
/*
|
||||
* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
* PROPRIETARY NOTICE (Combined)
|
||||
*
|
||||
* This source code is unpublished proprietary information
|
||||
* constituting, or derived under license from AT&T's UNIX(r) System V.
|
||||
* In addition, portions of such source code were derived from Berkeley
|
||||
* 4.3 BSD under license from the Regents of the University of
|
||||
* California.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Copyright Notice
|
||||
*
|
||||
* Notice of copyright on this source code product does not indicate
|
||||
* publication.
|
||||
*
|
||||
* (c) 1986,1987,1988.1989 Sun Microsystems, Inc
|
||||
* (c) 1983,1984,1985,1986,1987,1988,1989 AT&T.
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "sockmt.h"
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <stropts.h>
|
||||
#include <errno.h>
|
||||
#include <tiuser.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stream.h>
|
||||
#include <sys/sockmod.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "sock.h"
|
||||
|
||||
static int __connect(struct _si_user *siptr, struct sockaddr *name,
|
||||
int namelen, int nameflag, sigset_t *connmaskp);
|
||||
|
||||
#pragma weak connect = _connect
|
||||
|
||||
int
|
||||
_connect(s, name, namelen)
|
||||
register int s;
|
||||
register struct sockaddr *name;
|
||||
register int namelen;
|
||||
{
|
||||
struct _si_user *siptr;
|
||||
sigset_t mask;
|
||||
int retval;
|
||||
|
||||
if ((siptr = _s_checkfd(s)) == NULL)
|
||||
return (-1);
|
||||
|
||||
MUTEX_LOCK_SIGMASK(&siptr->lock, mask);
|
||||
retval = __connect(siptr, name, namelen, 1, &mask);
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
return (retval);
|
||||
}
|
||||
|
||||
static int
|
||||
__connect(siptr, name, namelen, nameflag, connmaskp)
|
||||
struct _si_user *siptr;
|
||||
register struct sockaddr *name;
|
||||
register int namelen;
|
||||
register int nameflag;
|
||||
sigset_t *connmaskp;
|
||||
{
|
||||
struct t_call sndcall;
|
||||
struct bind_ux bind_ux;
|
||||
|
||||
(void) memset((caddr_t)&sndcall, 0, sizeof (sndcall));
|
||||
|
||||
if (name && name->sa_family == AF_INET) {
|
||||
struct sockaddr_in *saddr_in;
|
||||
|
||||
if (namelen < sizeof (*saddr_in)) {
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
saddr_in = (struct sockaddr_in *)name;
|
||||
(void) memset(&saddr_in->sin_zero, 0, 8);
|
||||
}
|
||||
|
||||
if (name && name->sa_family == AF_UNIX) {
|
||||
struct stat rstat;
|
||||
struct sockaddr_un *un;
|
||||
int len;
|
||||
|
||||
if (siptr->udata.sockparams.sp_family != AF_UNIX) {
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
if (namelen > sizeof (name->sa_family)) {
|
||||
un = (struct sockaddr_un *)name;
|
||||
|
||||
if (namelen > sizeof (*un) ||
|
||||
(len = _s_uxpathlen(un)) ==
|
||||
sizeof (un->sun_path)) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
un->sun_path[len] = 0; /* Null terminate */
|
||||
|
||||
/*
|
||||
* Stat the file.
|
||||
*/
|
||||
#if defined(i386)
|
||||
if (_xstat(_STAT_VER, (caddr_t)un->sun_path,
|
||||
&rstat) < 0)
|
||||
#elif defined(sparc)
|
||||
if (_stat((caddr_t) un->sun_path, &rstat) < 0)
|
||||
#else
|
||||
#error Unknown architecture!
|
||||
#endif
|
||||
return (-1);
|
||||
|
||||
if ((rstat.st_mode & S_IFMT) != S_IFIFO) {
|
||||
errno = ENOTSOCK;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
(void) memset((caddr_t)&bind_ux, 0, sizeof (bind_ux));
|
||||
bind_ux.extdev = rstat.st_dev;
|
||||
bind_ux.extino = rstat.st_ino;
|
||||
bind_ux.extsize = sizeof (struct ux_dev);
|
||||
if (nameflag == 0)
|
||||
namelen = sizeof (name->sa_family);
|
||||
(void) memcpy((caddr_t)&bind_ux.name,
|
||||
(caddr_t)name, namelen);
|
||||
|
||||
sndcall.addr.buf = (caddr_t)&bind_ux;
|
||||
sndcall.addr.len = sizeof (bind_ux);
|
||||
} else {
|
||||
sndcall.addr.buf = NULL;
|
||||
sndcall.addr.len = 0;
|
||||
}
|
||||
} else {
|
||||
sndcall.addr.buf = (caddr_t)name;
|
||||
sndcall.addr.len = _s_min(namelen, siptr->udata.addrsize);
|
||||
}
|
||||
|
||||
return (_connect2(siptr, &sndcall, connmaskp));
|
||||
}
|
||||
|
||||
int
|
||||
_connect2(siptr, sndcall, connmaskp)
|
||||
register struct _si_user *siptr;
|
||||
register struct t_call *sndcall;
|
||||
sigset_t *connmaskp;
|
||||
{
|
||||
register int fctlflg;
|
||||
sigset_t procmask;
|
||||
struct strbuf ctlbuf;
|
||||
int didalloc = 0;
|
||||
|
||||
fctlflg = s_getfflags(siptr);
|
||||
|
||||
if (fctlflg&(O_NDELAY|O_NONBLOCK) && siptr->udata.servtype != T_CLTS) {
|
||||
/*
|
||||
* Secretly tell sockmod not to pass
|
||||
* up the T_CONN_CON, because we
|
||||
* are not going to wait for it.
|
||||
* (But dont tell anyone - especially
|
||||
* the transport provider).
|
||||
*/
|
||||
sndcall->opt.len = (ulong)-1; /* secret sign */
|
||||
}
|
||||
|
||||
/*
|
||||
* must be bound for TLI except TCP.
|
||||
*/
|
||||
if ((siptr->udata.so_state & SS_ISBOUND) == 0) {
|
||||
if (siptr->udata.sockparams.sp_family == AF_INET &&
|
||||
siptr->udata.sockparams.sp_type == SOCK_STREAM) {
|
||||
siptr->udata.so_state |= SS_ISBOUND;
|
||||
} else if (__bind(siptr, NULL, 0, NULL, NULL) < 0)
|
||||
return (-1);
|
||||
}
|
||||
/*
|
||||
* Acquire ctlbuf for use in sending/receiving
|
||||
*/
|
||||
ctlbuf.len = 0;
|
||||
if (siptr->ctlbuf) {
|
||||
ctlbuf.buf = siptr->ctlbuf;
|
||||
siptr->ctlbuf = NULL;
|
||||
ctlbuf.maxlen = siptr->ctlsize;
|
||||
} else {
|
||||
/*
|
||||
* siptr->ctlbuf is in use
|
||||
* allocate and free after use.
|
||||
*/
|
||||
if ((ctlbuf.maxlen = _s_cbuf_alloc(siptr,
|
||||
&ctlbuf.buf)) < 0)
|
||||
return (-1);
|
||||
didalloc = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Block all signals till T_CONN_REQ req sent and
|
||||
* acked with T_OK/ERROR_ACK
|
||||
*/
|
||||
_s_blockallsignals(&procmask);
|
||||
if (_s_snd_conn_req(siptr, sndcall, &ctlbuf) < 0) {
|
||||
_s_restoresigmask(&procmask);
|
||||
goto err_out;
|
||||
}
|
||||
_s_restoresigmask(&procmask);
|
||||
/*
|
||||
* If no delay, return with error if not CLTS.
|
||||
*/
|
||||
if (fctlflg&(O_NDELAY|O_NONBLOCK) && siptr->udata.servtype != T_CLTS) {
|
||||
errno = EINPROGRESS;
|
||||
siptr->udata.so_state |= SS_ISCONNECTING;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
/*
|
||||
* If CLTS, don't get the connection confirm.
|
||||
*/
|
||||
if (siptr->udata.servtype == T_CLTS) {
|
||||
if (sndcall->addr.len == 0)
|
||||
/*
|
||||
* Connect to Null address, breaks
|
||||
* the connection.
|
||||
*/
|
||||
siptr->udata.so_state &= ~SS_ISCONNECTED;
|
||||
else siptr->udata.so_state |= SS_ISCONNECTED;
|
||||
goto ok_out;
|
||||
}
|
||||
/*
|
||||
* This is a potentially blocking call.
|
||||
* In MT case, drop the lock and allow signals
|
||||
* and then reacquire the lock later
|
||||
*/
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, *connmaskp);
|
||||
if (_s_rcv_conn_con(siptr, &ctlbuf) < 0) {
|
||||
MUTEX_LOCK_SIGMASK(&siptr->lock, *connmaskp);
|
||||
goto err_out;
|
||||
}
|
||||
MUTEX_LOCK_SIGMASK(&siptr->lock, *connmaskp);
|
||||
|
||||
siptr->udata.so_state |= SS_ISCONNECTED;
|
||||
|
||||
ok_out:
|
||||
if (didalloc)
|
||||
free(ctlbuf.buf);
|
||||
else
|
||||
siptr->ctlbuf = ctlbuf.buf;
|
||||
|
||||
return (0);
|
||||
|
||||
err_out:
|
||||
if (didalloc)
|
||||
free(ctlbuf.buf);
|
||||
else
|
||||
siptr->ctlbuf = ctlbuf.buf;
|
||||
return (-1);
|
||||
}
|
||||
136
lib/libsocket/socket/getpeernm.c
Executable file
136
lib/libsocket/socket/getpeernm.c
Executable file
@@ -0,0 +1,136 @@
|
||||
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
|
||||
/* All Rights Reserved */
|
||||
|
||||
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
|
||||
/* The copyright notice above does not evidence any */
|
||||
/* actual or intended publication of such source code. */
|
||||
|
||||
#ident "@(#)getpeernm.c 1.11 93/12/25 SMI" /* SVr4.0 1.6 */
|
||||
|
||||
/*
|
||||
* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
* PROPRIETARY NOTICE (Combined)
|
||||
*
|
||||
* This source code is unpublished proprietary information
|
||||
* constituting, or derived under license from AT&T's UNIX(r) System V.
|
||||
* In addition, portions of such source code were derived from Berkeley
|
||||
* 4.3 BSD under license from the Regents of the University of
|
||||
* California.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Copyright Notice
|
||||
*
|
||||
* Notice of copyright on this source code product does not indicate
|
||||
* publication.
|
||||
*
|
||||
* (c) 1986,1987,1988.1989 Sun Microsystems, Inc
|
||||
* (c) 1983,1984,1985,1986,1987,1988,1989 AT&T.
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "sockmt.h"
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stream.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <stropts.h>
|
||||
#include <sys/tihdr.h>
|
||||
#include <sys/timod.h>
|
||||
#include <sys/socket.h>
|
||||
#include <tiuser.h>
|
||||
#include <sys/sockmod.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "sock.h"
|
||||
|
||||
#pragma weak getpeername = _getpeername
|
||||
|
||||
int
|
||||
_getpeername(s, name, namelen)
|
||||
register int s;
|
||||
register struct sockaddr *name;
|
||||
register int *namelen;
|
||||
{
|
||||
register struct _si_user *siptr;
|
||||
sigset_t mask;
|
||||
int retval;
|
||||
|
||||
if ((siptr = _s_checkfd(s)) == NULL)
|
||||
return (-1);
|
||||
|
||||
MUTEX_LOCK_SIGMASK(&siptr->lock, mask);
|
||||
if (name == NULL || namelen == NULL) {
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
retval = __getpeername(siptr, name, namelen);
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
return (retval);
|
||||
}
|
||||
|
||||
int
|
||||
__getpeername(siptr, name, namelen)
|
||||
register struct _si_user *siptr;
|
||||
register struct sockaddr *name;
|
||||
register int *namelen;
|
||||
{
|
||||
struct netbuf netbuf;
|
||||
int rval;
|
||||
int didalloc = 0;
|
||||
|
||||
netbuf.len = 0;
|
||||
if (siptr->ctlbuf) {
|
||||
netbuf.buf = siptr->ctlbuf;
|
||||
siptr->ctlbuf = NULL;
|
||||
netbuf.maxlen = siptr->ctlsize;
|
||||
} else {
|
||||
/*
|
||||
* siptr->ctlbuf is in use
|
||||
* allocate and free after use.
|
||||
*/
|
||||
rval = _s_cbuf_alloc(siptr, &netbuf.buf);
|
||||
if (rval < 0)
|
||||
return (-1);
|
||||
netbuf.maxlen = rval;
|
||||
didalloc = 1;
|
||||
}
|
||||
|
||||
do {
|
||||
rval = _ioctl(siptr->fd, TI_GETPEERNAME, &netbuf);
|
||||
} while (rval < 0 && errno == EINTR);
|
||||
|
||||
if (rval < 0) {
|
||||
switch (errno) {
|
||||
case ENXIO:
|
||||
case EPIPE:
|
||||
errno = ENOTCONN;
|
||||
break;
|
||||
|
||||
case ENOTTY:
|
||||
case ENODEV:
|
||||
case EINVAL:
|
||||
errno = ENOTSOCK;
|
||||
break;
|
||||
}
|
||||
if (didalloc)
|
||||
free(netbuf.buf);
|
||||
else
|
||||
siptr->ctlbuf = netbuf.buf;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
*namelen = _s_cpaddr(siptr, (char *)name, *namelen,
|
||||
netbuf.buf, netbuf.len);
|
||||
if (didalloc)
|
||||
free(netbuf.buf);
|
||||
else
|
||||
siptr->ctlbuf = netbuf.buf;
|
||||
return (0);
|
||||
}
|
||||
144
lib/libsocket/socket/getsocknm.c
Executable file
144
lib/libsocket/socket/getsocknm.c
Executable file
@@ -0,0 +1,144 @@
|
||||
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
|
||||
/* All Rights Reserved */
|
||||
|
||||
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
|
||||
/* The copyright notice above does not evidence any */
|
||||
/* actual or intended publication of such source code. */
|
||||
|
||||
#ident "@(#)getsocknm.c 1.11 93/12/25 SMI" /* SVr4.0 1.6 */
|
||||
|
||||
/*
|
||||
* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
* PROPRIETARY NOTICE (Combined)
|
||||
*
|
||||
* This source code is unpublished proprietary information
|
||||
* constituting, or derived under license from AT&T's UNIX(r) System V.
|
||||
* In addition, portions of such source code were derived from Berkeley
|
||||
* 4.3 BSD under license from the Regents of the University of
|
||||
* California.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Copyright Notice
|
||||
*
|
||||
* Notice of copyright on this source code product does not indicate
|
||||
* publication.
|
||||
*
|
||||
* (c) 1986,1987,1988.1989 Sun Microsystems, Inc
|
||||
* (c) 1983,1984,1985,1986,1987,1988,1989 AT&T.
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "sockmt.h"
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stream.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <stropts.h>
|
||||
#include <sys/tihdr.h>
|
||||
#include <sys/timod.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/socket.h>
|
||||
#include <tiuser.h>
|
||||
#include <sys/sockmod.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "sock.h"
|
||||
|
||||
#pragma weak getsockname = _getsockname
|
||||
|
||||
int
|
||||
_getsockname(s, name, namelen)
|
||||
register int s;
|
||||
register struct sockaddr *name;
|
||||
register int *namelen;
|
||||
{
|
||||
register struct _si_user *siptr;
|
||||
sigset_t mask;
|
||||
int retval;
|
||||
|
||||
if ((siptr = _s_checkfd(s)) == NULL)
|
||||
return (-1);
|
||||
|
||||
MUTEX_LOCK_SIGMASK(&siptr->lock, mask);
|
||||
if (name == NULL || namelen == NULL) {
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
retval = __getsockname(siptr, name, namelen);
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
return (retval);
|
||||
}
|
||||
|
||||
int
|
||||
__getsockname(siptr, name, namelen)
|
||||
register struct _si_user *siptr;
|
||||
register struct sockaddr *name;
|
||||
register int *namelen;
|
||||
{
|
||||
struct netbuf netbuf;
|
||||
int rval;
|
||||
int didalloc = 0;
|
||||
|
||||
netbuf.len = 0;
|
||||
if (siptr->ctlbuf) {
|
||||
netbuf.buf = siptr->ctlbuf;
|
||||
siptr->ctlbuf = NULL;
|
||||
netbuf.maxlen = siptr->ctlsize;
|
||||
} else {
|
||||
/*
|
||||
* siptr->ctlbuf is in use
|
||||
* allocate and free after use.
|
||||
*/
|
||||
rval = _s_cbuf_alloc(siptr, &netbuf.buf);
|
||||
if (rval < 0)
|
||||
return (-1);
|
||||
netbuf.maxlen = rval;
|
||||
didalloc = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get it from sockmod.
|
||||
*/
|
||||
do {
|
||||
rval = _ioctl(siptr->fd, TI_GETMYNAME, (caddr_t)&netbuf);
|
||||
} while (rval < 0 && errno == EINTR);
|
||||
|
||||
if (rval < 0) {
|
||||
switch (errno) {
|
||||
case ENXIO:
|
||||
case EPIPE:
|
||||
errno = 0;
|
||||
break;
|
||||
|
||||
case ENOTTY:
|
||||
case ENODEV:
|
||||
case EINVAL:
|
||||
errno = ENOTSOCK;
|
||||
break;
|
||||
}
|
||||
if (errno) {
|
||||
if (didalloc)
|
||||
free(netbuf.buf);
|
||||
else
|
||||
siptr->ctlbuf = netbuf.buf;
|
||||
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
*namelen = _s_cpaddr(siptr, (char *)name, *namelen,
|
||||
netbuf.buf, netbuf.len);
|
||||
if (didalloc)
|
||||
free(netbuf.buf);
|
||||
else
|
||||
siptr->ctlbuf = netbuf.buf;
|
||||
return (0);
|
||||
}
|
||||
149
lib/libsocket/socket/getsockopt.c
Executable file
149
lib/libsocket/socket/getsockopt.c
Executable file
@@ -0,0 +1,149 @@
|
||||
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
|
||||
/* All Rights Reserved */
|
||||
|
||||
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
|
||||
/* The copyright notice above does not evidence any */
|
||||
/* actual or intended publication of such source code. */
|
||||
|
||||
#ident "@(#)getsockopt.c 1.9 93/09/30 SMI" /* SVr4.0 1.5 */
|
||||
|
||||
/*
|
||||
* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
* PROPRIETARY NOTICE (Combined)
|
||||
*
|
||||
* This source code is unpublished proprietary information
|
||||
* constituting, or derived under license from AT&T's UNIX(r) System V.
|
||||
* In addition, portions of such source code were derived from Berkeley
|
||||
* 4.3 BSD under license from the Regents of the University of
|
||||
* California.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Copyright Notice
|
||||
*
|
||||
* Notice of copyright on this source code product does not indicate
|
||||
* publication.
|
||||
*
|
||||
* (c) 1986,1987,1988.1989 Sun Microsystems, Inc
|
||||
* (c) 1983,1984,1985,1986,1987,1988,1989 AT&T.
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "sockmt.h"
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stream.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <stropts.h>
|
||||
#include <sys/tihdr.h>
|
||||
#include <sys/timod.h>
|
||||
#include <sys/socket.h>
|
||||
#include <tiuser.h>
|
||||
#include <sys/sockmod.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "sock.h"
|
||||
|
||||
#pragma weak getsockopt = _getsockopt
|
||||
|
||||
int
|
||||
_getsockopt(s, level, optname, optval, optlen)
|
||||
register int s;
|
||||
register int level;
|
||||
register int optname;
|
||||
register char *optval;
|
||||
register int *optlen;
|
||||
{
|
||||
register struct T_optmgmt_req *opt_req;
|
||||
register struct T_optmgmt_ack *opt_ack;
|
||||
register struct _si_user *siptr;
|
||||
register int size;
|
||||
register struct opthdr *opt;
|
||||
char *cbuf;
|
||||
int retlen;
|
||||
int rval;
|
||||
sigset_t mask;
|
||||
int didalloc = 0;
|
||||
|
||||
if ((siptr = _s_checkfd(s)) == NULL)
|
||||
return (-1);
|
||||
|
||||
MUTEX_LOCK_SIGMASK(&siptr->lock, mask);
|
||||
if (level == SOL_SOCKET && optname == SO_TYPE) {
|
||||
if (*optlen < sizeof (int)) {
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
if (siptr->udata.servtype == T_CLTS)
|
||||
*(int *)optval = SOCK_DGRAM;
|
||||
else *(int *)optval = SOCK_STREAM;
|
||||
*optlen = sizeof (int);
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (siptr->ctlbuf) {
|
||||
cbuf = siptr->ctlbuf;
|
||||
siptr->ctlbuf = NULL;
|
||||
} else {
|
||||
/*
|
||||
* siptr->ctlbuf is in use
|
||||
* allocate and free after use.
|
||||
*/
|
||||
if (_s_cbuf_alloc(siptr, &cbuf) < 0)
|
||||
return (-1);
|
||||
didalloc = 1;
|
||||
}
|
||||
opt_req = (struct T_optmgmt_req *)cbuf;
|
||||
opt_req->PRIM_type = T_OPTMGMT_REQ;
|
||||
opt_req->OPT_length = sizeof (*opt) + *optlen;
|
||||
opt_req->OPT_offset = sizeof (*opt_req);
|
||||
opt_req->MGMT_flags = T_CHECK;
|
||||
size = sizeof (*opt_req) + opt_req->OPT_length;
|
||||
|
||||
opt = (struct opthdr *)(cbuf + opt_req->OPT_offset);
|
||||
opt->level = level;
|
||||
opt->name = optname;
|
||||
opt->len = *optlen;
|
||||
|
||||
do {
|
||||
rval = _s_do_ioctl(s, cbuf, size, TI_OPTMGMT, &retlen);
|
||||
} while (! rval && errno == EINTR);
|
||||
|
||||
if (! rval) {
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
if (retlen < (sizeof (*opt_ack) + sizeof (*opt))) {
|
||||
errno = EPROTO;
|
||||
goto err_out;
|
||||
}
|
||||
opt_ack = (struct T_optmgmt_ack *)cbuf;
|
||||
opt = (struct opthdr *)(cbuf + opt_ack->OPT_offset);
|
||||
(void) memcpy(optval, (caddr_t)opt + sizeof (*opt), opt->len);
|
||||
*optlen = opt->len;
|
||||
|
||||
if (didalloc)
|
||||
free(cbuf);
|
||||
else
|
||||
siptr->ctlbuf = cbuf;
|
||||
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
|
||||
return (0);
|
||||
|
||||
err_out:
|
||||
|
||||
if (didalloc)
|
||||
free(cbuf);
|
||||
else
|
||||
siptr->ctlbuf = cbuf;
|
||||
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
return (-1);
|
||||
}
|
||||
146
lib/libsocket/socket/listen.c
Executable file
146
lib/libsocket/socket/listen.c
Executable file
@@ -0,0 +1,146 @@
|
||||
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
|
||||
/* All Rights Reserved */
|
||||
|
||||
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
|
||||
/* The copyright notice above does not evidence any */
|
||||
/* actual or intended publication of such source code. */
|
||||
|
||||
#ident "@(#)listen.c 1.12 94/01/04 SMI" /* SVr4.0 1.8 */
|
||||
|
||||
/*
|
||||
* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
* PROPRIETARY NOTICE (Combined)
|
||||
*
|
||||
* This source code is unpublished proprietary information
|
||||
* constituting, or derived under license from AT&T's UNIX(r) System V.
|
||||
* In addition, portions of such source code were derived from Berkeley
|
||||
* 4.3 BSD under license from the Regents of the University of
|
||||
* California.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Copyright Notice
|
||||
*
|
||||
* Notice of copyright on this source code product does not indicate
|
||||
* publication.
|
||||
*
|
||||
* (c) 1986,1987,1988.1989 Sun Microsystems, Inc
|
||||
* (c) 1983,1984,1985,1986,1987,1988,1989 AT&T.
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "sockmt.h"
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stream.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <stropts.h>
|
||||
#include <sys/tihdr.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/socket.h>
|
||||
#include <tiuser.h>
|
||||
#include <sys/sockmod.h>
|
||||
#include <signal.h>
|
||||
#include <syslog.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "sock.h"
|
||||
|
||||
#pragma weak listen = _listen
|
||||
|
||||
/*
|
||||
* We make the socket module do the unbind,
|
||||
* if necessary, to make the timing window
|
||||
* of error as small as possible.
|
||||
*/
|
||||
int
|
||||
_listen(s, qlen)
|
||||
register int s;
|
||||
register int qlen;
|
||||
{
|
||||
register struct T_bind_req *bind_req;
|
||||
register struct _si_user *siptr;
|
||||
char *cbuf;
|
||||
sigset_t procmask;
|
||||
sigset_t mask;
|
||||
int didalloc = 0;
|
||||
|
||||
if ((siptr = _s_checkfd(s)) == NULL)
|
||||
return (-1);
|
||||
|
||||
MUTEX_LOCK_SIGMASK(&siptr->lock, mask);
|
||||
if (siptr->udata.servtype == T_CLTS) {
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
errno = EOPNOTSUPP;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the socket is ready to accept connections already, then
|
||||
* return without doing anything. This avoids a problem where
|
||||
* a second listen() call fails if a connection is pending and
|
||||
* leaves the socket unbound.
|
||||
*/
|
||||
if ((siptr->udata.so_options & SO_ACCEPTCONN) != 0) {
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (siptr->ctlbuf) {
|
||||
cbuf = siptr->ctlbuf;
|
||||
siptr->ctlbuf = NULL;
|
||||
} else {
|
||||
/*
|
||||
* siptr->ctlbuf is in use
|
||||
* allocate and free after use.
|
||||
*/
|
||||
if (_s_cbuf_alloc(siptr, &cbuf) < 0)
|
||||
return (-1);
|
||||
didalloc = 1;
|
||||
}
|
||||
bind_req = (struct T_bind_req *)cbuf;
|
||||
|
||||
bind_req->PRIM_type = T_BIND_REQ;
|
||||
bind_req->ADDR_offset = sizeof (*bind_req);
|
||||
bind_req->CONIND_number = qlen + 1;
|
||||
|
||||
if ((siptr->udata.so_state & SS_ISBOUND) == 0) {
|
||||
/*
|
||||
* Must have been explicitly bound in the UNIX domain.
|
||||
*/
|
||||
if (siptr->udata.sockparams.sp_family == AF_UNIX) {
|
||||
errno = EINVAL;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
bind_req->ADDR_length = 0;
|
||||
} else bind_req->ADDR_length = siptr->udata.addrsize;
|
||||
|
||||
_s_blockallsignals(&procmask);
|
||||
if (!_s_do_ioctl(s, cbuf, sizeof (*bind_req) +
|
||||
bind_req->ADDR_length, SI_LISTEN, NULL)) {
|
||||
_s_restoresigmask(&procmask);
|
||||
goto err_out;
|
||||
}
|
||||
_s_restoresigmask(&procmask);
|
||||
|
||||
siptr->udata.so_options |= SO_ACCEPTCONN;
|
||||
if (didalloc)
|
||||
free(cbuf);
|
||||
else
|
||||
siptr->ctlbuf = cbuf;
|
||||
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
return (0);
|
||||
|
||||
err_out:
|
||||
if (didalloc)
|
||||
free(cbuf);
|
||||
else
|
||||
siptr->ctlbuf = cbuf;
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
return (-1);
|
||||
}
|
||||
170
lib/libsocket/socket/receive.c
Executable file
170
lib/libsocket/socket/receive.c
Executable file
@@ -0,0 +1,170 @@
|
||||
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
|
||||
/* All Rights Reserved */
|
||||
|
||||
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
|
||||
/* The copyright notice above does not evidence any */
|
||||
/* actual or intended publication of such source code. */
|
||||
|
||||
#ident "@(#)receive.c 1.12 94/02/02 SMI" /* SVr4.0 1.5 */
|
||||
|
||||
/*
|
||||
* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
* PROPRIETARY NOTICE (Combined)
|
||||
*
|
||||
* This source code is unpublished proprietary information
|
||||
* constituting, or derived under license from AT&T's UNIX(r) System V.
|
||||
* In addition, portions of such source code were derived from Berkeley
|
||||
* 4.3 BSD under license from the Regents of the University of
|
||||
* California.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Copyright Notice
|
||||
*
|
||||
* Notice of copyright on this source code product does not indicate
|
||||
* publication.
|
||||
*
|
||||
* (c) 1986,1987,1988.1989 Sun Microsystems, Inc
|
||||
* (c) 1983,1984,1985,1986,1987,1988,1989 AT&T.
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "sockmt.h"
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stream.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <stropts.h>
|
||||
#include <sys/tihdr.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/socket.h>
|
||||
#include <tiuser.h>
|
||||
#include <sys/sockmod.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "sock.h"
|
||||
|
||||
#pragma weak recvmsg = _recvmsg
|
||||
#pragma weak recvfrom = _recvfrom
|
||||
#pragma weak recv = _recv
|
||||
|
||||
int
|
||||
_recvmsg(s, msg, flags)
|
||||
register int s;
|
||||
register struct msghdr *msg;
|
||||
register int flags;
|
||||
{
|
||||
register struct _si_user *siptr;
|
||||
char *buf;
|
||||
int len;
|
||||
int retval;
|
||||
sigset_t mask;
|
||||
|
||||
if (msg->msg_iovlen > 1) {
|
||||
int i;
|
||||
sigset_t procmask;
|
||||
|
||||
for (i = 0, len = 0; i < msg->msg_iovlen; i++)
|
||||
len += msg->msg_iov[i].iov_len;
|
||||
/*
|
||||
* block all signals while allocating memory
|
||||
*/
|
||||
_s_blockallsignals(&procmask);
|
||||
if ((buf = malloc(len)) == NULL) {
|
||||
_s_restoresigmask(&procmask);
|
||||
errno = ENOMEM;
|
||||
return (-1);
|
||||
}
|
||||
_s_restoresigmask(&procmask);
|
||||
} else {
|
||||
buf = msg->msg_iov[0].iov_base;
|
||||
len = msg->msg_iov[0].iov_len;
|
||||
}
|
||||
|
||||
if ((siptr = _s_checkfd(s)) == NULL)
|
||||
return (-1);
|
||||
|
||||
MUTEX_LOCK_SIGMASK(&siptr->lock, mask);
|
||||
retval = _s_soreceivexx(siptr, flags, buf, len,
|
||||
(struct sockaddr *)msg->msg_name,
|
||||
&msg->msg_namelen, msg->msg_accrights,
|
||||
&msg->msg_accrightslen, &mask);
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
if (msg->msg_iovlen > 1) {
|
||||
sigset_t procmask;
|
||||
|
||||
if (retval > 0) {
|
||||
/*
|
||||
* Copy it all back as per the users
|
||||
* request.
|
||||
*/
|
||||
register int count, i, len, pos;
|
||||
|
||||
for (i = pos = 0, len = retval; i < msg->msg_iovlen;
|
||||
i++) {
|
||||
count = _s_min(msg->msg_iov[i].iov_len, len);
|
||||
(void) memcpy(msg->msg_iov[i].iov_base,
|
||||
&buf[pos], count);
|
||||
pos += count;
|
||||
len -= count;
|
||||
if (len == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* block all signals while freeing memory
|
||||
*/
|
||||
_s_blockallsignals(&procmask);
|
||||
free(buf);
|
||||
_s_restoresigmask(&procmask);
|
||||
}
|
||||
return (retval);
|
||||
}
|
||||
|
||||
int
|
||||
_recvfrom(s, buf, len, flags, from, fromlen)
|
||||
register int s;
|
||||
register char *buf;
|
||||
register u_long len;
|
||||
register int flags;
|
||||
register struct sockaddr *from;
|
||||
register int *fromlen;
|
||||
{
|
||||
register struct _si_user *siptr;
|
||||
sigset_t mask;
|
||||
int retval;
|
||||
|
||||
if ((siptr = _s_checkfd(s)) == NULL)
|
||||
return (-1);
|
||||
|
||||
MUTEX_LOCK_SIGMASK(&siptr->lock, mask);
|
||||
retval = _s_soreceivexx(siptr, flags, buf, len, from, fromlen,
|
||||
NULL, NULL, &mask);
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
return (retval);
|
||||
}
|
||||
|
||||
int
|
||||
_recv(s, buf, len, flags)
|
||||
register int s;
|
||||
register char *buf;
|
||||
register u_long len;
|
||||
register int flags;
|
||||
{
|
||||
register struct _si_user *siptr;
|
||||
sigset_t mask;
|
||||
int retval;
|
||||
|
||||
if ((siptr = _s_checkfd(s)) == NULL)
|
||||
return (-1);
|
||||
|
||||
MUTEX_LOCK_SIGMASK(&siptr->lock, mask);
|
||||
retval = _s_soreceivexx(siptr, flags, buf, len, NULL, NULL,
|
||||
NULL, NULL, &mask);
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
return (retval);
|
||||
}
|
||||
365
lib/libsocket/socket/s_ioctl.c
Executable file
365
lib/libsocket/socket/s_ioctl.c
Executable file
@@ -0,0 +1,365 @@
|
||||
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
|
||||
/* All Rights Reserved */
|
||||
|
||||
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
|
||||
/* The copyright notice above does not evidence any */
|
||||
/* actual or intended publication of such source code. */
|
||||
|
||||
#ident "@(#)s_ioctl.c 1.18 95/03/10 SMI" /* SVr4.0 1.7 */
|
||||
|
||||
/*
|
||||
* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
* PROPRIETARY NOTICE (Combined)
|
||||
*
|
||||
* This source code is unpublished proprietary information
|
||||
* constituting, or derived under license from AT&T's UNIX(r) System V.
|
||||
* In addition, portions of such source code were derived from Berkeley
|
||||
* 4.3 BSD under license from the Regents of the University of
|
||||
* California.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Copyright Notice
|
||||
*
|
||||
* Notice of copyright on this source code product does not indicate
|
||||
* publication.
|
||||
*
|
||||
* (c) 1986,1987,1988.1989 Sun Microsystems, Inc
|
||||
* (c) 1983,1984,1985,1986,1987,1988,1989 AT&T.
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "sockmt.h"
|
||||
#include <sys/param.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/filio.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <stropts.h>
|
||||
#include <signal.h>
|
||||
#include <sys/termios.h>
|
||||
#include <sys/socket.h>
|
||||
#include <tiuser.h>
|
||||
#include <sys/stream.h>
|
||||
#include <sys/sockmod.h>
|
||||
#include <errno.h>
|
||||
#include <syslog.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "sock.h"
|
||||
|
||||
/*
|
||||
* Multi-threading note:
|
||||
* The following ioctls and fcntls can not be issued from within the socket
|
||||
* library while holding the siptr->lock (since the s_ioctl or s_fcntl code
|
||||
* acquires that lock themselves):
|
||||
* FIOCASYNC
|
||||
* SIOCSPGRP
|
||||
* FIOCSETOWN
|
||||
*/
|
||||
|
||||
|
||||
#pragma weak fcntl = s_fcntl
|
||||
#pragma weak ioctl = s_ioctl
|
||||
|
||||
#define ISSOCK(A) (_ioctl((A), I_FIND, "sockmod"))
|
||||
|
||||
static int _s_dofioasync(int des, int *arg);
|
||||
int s_ioctl(int des, int request, char *arg);
|
||||
|
||||
int
|
||||
s_fcntl(des, cmd, arg)
|
||||
register int des;
|
||||
register int cmd;
|
||||
int arg;
|
||||
|
||||
{
|
||||
int res;
|
||||
|
||||
switch (cmd) {
|
||||
case F_SETOWN:
|
||||
SOCKDEBUG((struct _si_user *)NULL,
|
||||
"fcntl: got fcntl-F_SETOWN\n", 0);
|
||||
return (s_ioctl(des, FIOSETOWN, (char *)&arg));
|
||||
|
||||
case F_GETOWN:
|
||||
SOCKDEBUG((struct _si_user *)NULL,
|
||||
"fcntl: got fcntl-F_GETOWN\n", 0);
|
||||
if (s_ioctl(des, FIOGETOWN, (char *)&res) < 0)
|
||||
return (-1);
|
||||
return (res);
|
||||
|
||||
case F_SETFL:
|
||||
SOCKDEBUG((struct _si_user *)NULL,
|
||||
"fcntl: got fcntl-F_SETFL\n", 0);
|
||||
if (ISSOCK(des) == 1) {
|
||||
register struct _si_user *siptr;
|
||||
|
||||
/* Need to have fflags track the kernel flags */
|
||||
if ((siptr = _s_checkfd(des)) != NULL)
|
||||
s_invalfflags(siptr);
|
||||
res = arg & FASYNC;
|
||||
if (_s_dofioasync(des, &res) < 0)
|
||||
return (-1);
|
||||
}
|
||||
errno = 0;
|
||||
return (_fcntl(des, cmd, arg));
|
||||
|
||||
case F_GETFL: {
|
||||
register int flags;
|
||||
|
||||
SOCKDEBUG((struct _si_user *)NULL,
|
||||
"fcntl: got fcntl-F_GETFL\n", 0);
|
||||
if ((flags = _fcntl(des, cmd, arg)) < 0)
|
||||
return (-1);
|
||||
|
||||
if (ISSOCK(des) == 1) {
|
||||
register struct _si_user *siptr;
|
||||
|
||||
/*
|
||||
* See if SIGIO is in force.
|
||||
*/
|
||||
if ((siptr = _s_checkfd(des)) !=
|
||||
(struct _si_user *)NULL) {
|
||||
if ((siptr->flags & S_SIGIO) != 0)
|
||||
flags |= FASYNC;
|
||||
}
|
||||
}
|
||||
errno = 0;
|
||||
return (flags);
|
||||
}
|
||||
|
||||
default:
|
||||
return (_fcntl(des, cmd, arg));
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
s_ioctl(des, request, arg)
|
||||
register int des;
|
||||
register int request;
|
||||
char *arg;
|
||||
{
|
||||
pid_t pid;
|
||||
int retval;
|
||||
int sv_errno;
|
||||
struct _si_user *siptr;
|
||||
|
||||
SOCKDEBUG((struct _si_user *)NULL,
|
||||
"ioctl: got ioctl request %x\n", request);
|
||||
switch (request) {
|
||||
case FIOASYNC:
|
||||
case FIOSETOWN:
|
||||
case FIOGETOWN:
|
||||
case SIOCSPGRP:
|
||||
case SIOCGPGRP:
|
||||
case SIOCATMARK:
|
||||
if (ISSOCK(des) != 1) {
|
||||
if (request == SIOCSPGRP || request == SIOCGPGRP ||
|
||||
request == SIOCATMARK) {
|
||||
SOCKDEBUG((struct _si_user *)NULL,
|
||||
"ioctl: %d not socket\n", des);
|
||||
errno = ENOTSOCK;
|
||||
return (-1);
|
||||
} else {
|
||||
errno = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (request) {
|
||||
case FIOASYNC:
|
||||
/*
|
||||
* Facilitate SIGIO.
|
||||
*/
|
||||
return (_s_dofioasync(des, (int *)arg));
|
||||
|
||||
case SIOCGPGRP:
|
||||
case FIOGETOWN:
|
||||
SOCKDEBUG((struct _si_user *)NULL,
|
||||
"ioctl: got SIOCGPGRP/FIOGETOWN\n", 0);
|
||||
retval = 0;
|
||||
if (_ioctl(des, I_GETSIG, &retval) < 0) {
|
||||
if (errno == EINVAL) {
|
||||
retval = 0;
|
||||
} else return (-1);
|
||||
}
|
||||
if (retval & (S_RDBAND|S_BANDURG|S_RDNORM|S_WRNORM))
|
||||
*(pid_t *)arg = getpid();
|
||||
else *(pid_t *)arg = 0;
|
||||
return (0);
|
||||
|
||||
case SIOCSPGRP:
|
||||
case FIOSETOWN: {
|
||||
sigset_t mask;
|
||||
|
||||
/*
|
||||
* Facilitate receipt of SIGURG.
|
||||
*
|
||||
* We are forgiving in that if a
|
||||
* process group was specified rather
|
||||
* than a process id, we will only
|
||||
* fail it if the process group
|
||||
* specified is not the callers.
|
||||
*/
|
||||
SOCKDEBUG((struct _si_user *)NULL,
|
||||
"ioctl: got SIOCSPGRP/FIOSETOWN\n", 0);
|
||||
pid = *(pid_t *)arg;
|
||||
if (pid < 0) {
|
||||
pid = -pid;
|
||||
if (pid != getpgrp()) {
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
} else if (pid != 0) {
|
||||
if (pid != getpid()) {
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
if ((siptr = _s_checkfd(des)) ==
|
||||
(struct _si_user *)NULL)
|
||||
return (-1);
|
||||
|
||||
MUTEX_LOCK_SIGMASK(&siptr->lock, mask);
|
||||
retval = 0;
|
||||
if (pid != 0) {
|
||||
if (siptr->flags & S_SIGIO)
|
||||
retval = S_RDNORM|S_WRNORM;
|
||||
retval |= S_RDBAND|S_BANDURG;
|
||||
}
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
if (_ioctl(des, I_SETSIG, retval) < 0) {
|
||||
(void) syslog(LOG_ERR,
|
||||
"ioctl: I_SETSIG failed %d\n", errno);
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
case SIOCATMARK:
|
||||
SOCKDEBUG((struct _si_user *)NULL,
|
||||
"ioctl: got SIOCATMARK\n", 0);
|
||||
if ((retval = _ioctl(des, I_ATMARK, LASTMARK)) < 0)
|
||||
return (-1);
|
||||
*(int *)arg = retval;
|
||||
return (0);
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
SOCKDEBUG((struct _si_user *)NULL,
|
||||
"ioctl: match failed, calling regular ioctl\n", 0);
|
||||
|
||||
retval = _ioctl(des, request, arg);
|
||||
sv_errno = errno;
|
||||
if ((retval != -1) &&
|
||||
(siptr = find_silink(des)) != (struct _si_user *) NULL)
|
||||
s_invalfflags(siptr);
|
||||
errno = sv_errno;
|
||||
return (retval);
|
||||
}
|
||||
|
||||
/*
|
||||
* s_getfflags() and s_invalfflags() operate as a cache for the file flags.
|
||||
*/
|
||||
int
|
||||
s_getfflags(siptr)
|
||||
register struct _si_user *siptr;
|
||||
{
|
||||
int save_errno;
|
||||
|
||||
save_errno = errno;
|
||||
if (siptr->fflags == -1) {
|
||||
siptr->fflags = _fcntl(siptr->fd, F_GETFL, 0);
|
||||
if (siptr->fflags == -1) {
|
||||
(void) syslog(LOG_ERR,
|
||||
"s_getfflags: fcntl: F_GETFL failed, errno %d\n",
|
||||
errno);
|
||||
save_errno = 0;
|
||||
}
|
||||
}
|
||||
errno = save_errno;
|
||||
return (siptr->fflags);
|
||||
}
|
||||
|
||||
void
|
||||
s_invalfflags(siptr)
|
||||
register struct _si_user *siptr;
|
||||
{
|
||||
siptr->fflags = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable or disable asynchronous I/O
|
||||
*/
|
||||
static int
|
||||
_s_dofioasync(des, arg)
|
||||
register int des;
|
||||
register int *arg;
|
||||
{
|
||||
register struct _si_user *siptr;
|
||||
int retval;
|
||||
sigset_t mask;
|
||||
|
||||
SOCKDEBUG((struct _si_user *)NULL, "_s_dofioasync: Entered, %d\n",
|
||||
*arg);
|
||||
|
||||
if ((siptr = _s_checkfd(des)) == (struct _si_user *)NULL)
|
||||
return (-1);
|
||||
|
||||
MUTEX_LOCK_SIGMASK(&siptr->lock, mask);
|
||||
/*
|
||||
* Turn on or off async I/O.
|
||||
*/
|
||||
retval = 0;
|
||||
if (*arg) {
|
||||
/*
|
||||
* Turn ON SIGIO if
|
||||
* it is not already on.
|
||||
*/
|
||||
if ((siptr->flags & S_SIGIO) != 0) {
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
return (0);
|
||||
}
|
||||
|
||||
SOCKDEBUG((struct _si_user *)NULL,
|
||||
"_s_dofioasync: Setting SIGIO\n", 0);
|
||||
|
||||
if (siptr->flags & S_SIGURG)
|
||||
retval = S_RDBAND|S_BANDURG;
|
||||
retval |= S_RDNORM|S_WRNORM;
|
||||
if (_ioctl(des, I_SETSIG, retval) < 0)
|
||||
return (-1);
|
||||
|
||||
siptr->flags |= S_SIGIO;
|
||||
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Turn OFF SIGIO if
|
||||
* not already off.
|
||||
*/
|
||||
if ((siptr->flags & S_SIGIO) == 0) {
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
return (0);
|
||||
}
|
||||
|
||||
SOCKDEBUG((struct _si_user *)NULL,
|
||||
"_s_dofioasync: Re-setting SIGIO\n", 0);
|
||||
|
||||
siptr->flags &= ~S_SIGIO;
|
||||
|
||||
if (siptr->flags & S_SIGURG)
|
||||
retval = S_RDBAND|S_BANDURG;
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
return (_ioctl(des, I_SETSIG, retval));
|
||||
}
|
||||
162
lib/libsocket/socket/send.c
Executable file
162
lib/libsocket/socket/send.c
Executable file
@@ -0,0 +1,162 @@
|
||||
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
|
||||
/* All Rights Reserved */
|
||||
|
||||
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
|
||||
/* The copyright notice above does not evidence any */
|
||||
/* actual or intended publication of such source code. */
|
||||
|
||||
#ident "@(#)send.c 1.11 94/02/02 SMI" /* SVr4.0 1.5 */
|
||||
|
||||
/*
|
||||
* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
* PROPRIETARY NOTICE (Combined)
|
||||
*
|
||||
* This source code is unpublished proprietary information
|
||||
* constituting, or derived under license from AT&T's UNIX(r) System V.
|
||||
* In addition, portions of such source code were derived from Berkeley
|
||||
* 4.3 BSD under license from the Regents of the University of
|
||||
* California.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Copyright Notice
|
||||
*
|
||||
* Notice of copyright on this source code product does not indicate
|
||||
* publication.
|
||||
*
|
||||
* (c) 1986,1987,1988.1989 Sun Microsystems, Inc
|
||||
* (c) 1983,1984,1985,1986,1987,1988,1989 AT&T.
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "sockmt.h"
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stream.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <stropts.h>
|
||||
#include <sys/tihdr.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/uio.h>
|
||||
#include <tiuser.h>
|
||||
#include <sys/sockmod.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "sock.h"
|
||||
|
||||
#pragma weak sendmsg = _sendmsg
|
||||
#pragma weak sendto = _sendto
|
||||
#pragma weak send = _send
|
||||
|
||||
|
||||
int
|
||||
_sendmsg(s, msg, flags)
|
||||
register int s;
|
||||
register struct msghdr *msg;
|
||||
register int flags;
|
||||
{
|
||||
register struct _si_user *siptr;
|
||||
int len;
|
||||
char *buf;
|
||||
int retval;
|
||||
sigset_t mask;
|
||||
|
||||
if ((siptr = _s_checkfd(s)) == NULL)
|
||||
return (-1);
|
||||
|
||||
if (msg->msg_iovlen > 1) {
|
||||
/*
|
||||
* Have to make one buffer
|
||||
*/
|
||||
int i, pos;
|
||||
sigset_t procmask;
|
||||
|
||||
for (i = 0, len = 0; i < msg->msg_iovlen; i++)
|
||||
len += msg->msg_iov[i].iov_len;
|
||||
/*
|
||||
* block all signals while allocating memory
|
||||
*/
|
||||
_s_blockallsignals(&procmask);
|
||||
if ((buf = malloc(len)) == NULL) {
|
||||
_s_restoresigmask(&procmask);
|
||||
errno = ENOMEM;
|
||||
return (-1);
|
||||
}
|
||||
_s_restoresigmask(&procmask);
|
||||
|
||||
for (i = 0, pos = 0; i < msg->msg_iovlen; i++) {
|
||||
(void) memcpy(&buf[pos], msg->msg_iov[i].iov_base,
|
||||
msg->msg_iov[i].iov_len);
|
||||
pos += msg->msg_iov[i].iov_len;
|
||||
}
|
||||
} else {
|
||||
buf = msg->msg_iov[0].iov_base;
|
||||
len = msg->msg_iov[0].iov_len;
|
||||
}
|
||||
|
||||
MUTEX_LOCK_SIGMASK(&siptr->lock, mask);
|
||||
retval = _s_sosendxx(siptr, flags, buf, len,
|
||||
(struct sockaddr *)msg->msg_name,
|
||||
msg->msg_namelen,
|
||||
msg->msg_accrights, msg->msg_accrightslen,
|
||||
&mask);
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
if (msg->msg_iovlen > 1) {
|
||||
/*
|
||||
* block all signals while freeing memory
|
||||
*/
|
||||
sigset_t procmask;
|
||||
|
||||
_s_blockallsignals(&procmask);
|
||||
free(buf);
|
||||
_s_restoresigmask(&procmask);
|
||||
}
|
||||
return (retval);
|
||||
}
|
||||
|
||||
int
|
||||
_sendto(s, buf, len, flags, to, tolen)
|
||||
register int s;
|
||||
register char *buf;
|
||||
register int len;
|
||||
register int flags;
|
||||
register struct sockaddr *to;
|
||||
register int tolen;
|
||||
{
|
||||
register struct _si_user *siptr;
|
||||
sigset_t mask;
|
||||
int retval;
|
||||
|
||||
if ((siptr = _s_checkfd(s)) == NULL)
|
||||
return (-1);
|
||||
|
||||
MUTEX_LOCK_SIGMASK(&siptr->lock, mask);
|
||||
retval = _s_sosendxx(siptr, flags, buf, len, to, tolen, NULL, 0,
|
||||
&mask);
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
return (retval);
|
||||
}
|
||||
|
||||
int
|
||||
_send(s, buf, len, flags)
|
||||
register int s;
|
||||
register char *buf;
|
||||
register int len;
|
||||
register int flags;
|
||||
{
|
||||
register struct _si_user *siptr;
|
||||
sigset_t mask;
|
||||
int retval;
|
||||
|
||||
if ((siptr = _s_checkfd(s)) == NULL)
|
||||
return (-1);
|
||||
|
||||
MUTEX_LOCK_SIGMASK(&siptr->lock, mask);
|
||||
retval = _s_sosendxx(siptr, flags, buf, len, NULL, 0, NULL, 0, &mask);
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
return (retval);
|
||||
}
|
||||
99
lib/libsocket/socket/setpeernm.c
Executable file
99
lib/libsocket/socket/setpeernm.c
Executable file
@@ -0,0 +1,99 @@
|
||||
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
|
||||
/* All Rights Reserved */
|
||||
|
||||
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
|
||||
/* The copyright notice above does not evidence any */
|
||||
/* actual or intended publication of such source code. */
|
||||
|
||||
#ident "@(#)setpeernm.c 1.9 93/09/30 SMI" /* SVr4.0 1.5 */
|
||||
|
||||
/*
|
||||
* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
* PROPRIETARY NOTICE (Combined)
|
||||
*
|
||||
* This source code is unpublished proprietary information
|
||||
* constituting, or derived under license from AT&T's UNIX(r) System V.
|
||||
* In addition, portions of such source code were derived from Berkeley
|
||||
* 4.3 BSD under license from the Regents of the University of
|
||||
* California.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Copyright Notice
|
||||
*
|
||||
* Notice of copyright on this source code product does not indicate
|
||||
* publication.
|
||||
*
|
||||
* (c) 1986,1987,1988.1989 Sun Microsystems, Inc
|
||||
* (c) 1983,1984,1985,1986,1987,1988,1989 AT&T.
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "sockmt.h"
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stream.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <stropts.h>
|
||||
#include <sys/tihdr.h>
|
||||
#include <sys/socket.h>
|
||||
#include <tiuser.h>
|
||||
#include <sys/sockmod.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "sock.h"
|
||||
|
||||
static int __setpeername(struct _si_user *siptr, struct sockaddr *name,
|
||||
int namelen);
|
||||
|
||||
#pragma weak setpeername = _setpeername
|
||||
|
||||
int
|
||||
_setpeername(s, name, namelen)
|
||||
register int s;
|
||||
register struct sockaddr *name;
|
||||
register int namelen;
|
||||
{
|
||||
register struct _si_user *siptr;
|
||||
sigset_t mask;
|
||||
int retval;
|
||||
|
||||
if ((siptr = _s_checkfd(s)) == (struct _si_user *)NULL)
|
||||
return (-1);
|
||||
|
||||
MUTEX_LOCK_SIGMASK(&siptr->lock, mask);
|
||||
if (namelen <= 0) {
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
retval = __setpeername(siptr, name,
|
||||
_s_min(namelen, siptr->udata.addrsize));
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
return (retval);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
__setpeername(siptr, name, namelen)
|
||||
register struct _si_user *siptr;
|
||||
register struct sockaddr *name;
|
||||
register int namelen;
|
||||
{
|
||||
sigset_t procmask;
|
||||
|
||||
_s_blockallsignals(&procmask);
|
||||
if (!_s_do_ioctl(siptr->fd, (caddr_t)name, namelen,
|
||||
SI_SETPEERNAME, NULL)) {
|
||||
_s_restoresigmask(&procmask);
|
||||
return (-1);
|
||||
}
|
||||
_s_restoresigmask(&procmask);
|
||||
|
||||
return (0);
|
||||
}
|
||||
95
lib/libsocket/socket/setsocknm.c
Executable file
95
lib/libsocket/socket/setsocknm.c
Executable file
@@ -0,0 +1,95 @@
|
||||
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
|
||||
/* All Rights Reserved */
|
||||
|
||||
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
|
||||
/* The copyright notice above does not evidence any */
|
||||
/* actual or intended publication of such source code. */
|
||||
|
||||
#ident "@(#)setsocknm.c 1.9 93/09/30 SMI" /* SVr4.0 1.5 */
|
||||
|
||||
/*
|
||||
* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
* PROPRIETARY NOTICE (Combined)
|
||||
*
|
||||
* This source code is unpublished proprietary information
|
||||
* constituting, or derived under license from AT&T's UNIX(r) System V.
|
||||
* In addition, portions of such source code were derived from Berkeley
|
||||
* 4.3 BSD under license from the Regents of the University of
|
||||
* California.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Copyright Notice
|
||||
*
|
||||
* Notice of copyright on this source code product does not indicate
|
||||
* publication.
|
||||
*
|
||||
* (c) 1986,1987,1988.1989 Sun Microsystems, Inc
|
||||
* (c) 1983,1984,1985,1986,1987,1988,1989 AT&T.
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "sockmt.h"
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stream.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <stropts.h>
|
||||
#include <sys/tihdr.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/socket.h>
|
||||
#include <tiuser.h>
|
||||
#include <sys/sockmod.h>
|
||||
#include <signal.h>
|
||||
|
||||
static int _setsockname(struct _si_user *siptr, struct sockaddr *name,
|
||||
int namelen);
|
||||
|
||||
|
||||
int
|
||||
setsockname(s, name, namelen)
|
||||
register int s;
|
||||
register struct sockaddr *name;
|
||||
register int namelen;
|
||||
{
|
||||
register struct _si_user *siptr;
|
||||
sigset_t mask;
|
||||
int retval;
|
||||
|
||||
if ((siptr = _s_checkfd(s)) == (struct _si_user *)NULL)
|
||||
return (-1);
|
||||
|
||||
MUTEX_LOCK_SIGMASK(&siptr->lock, mask);
|
||||
if (namelen <= 0) {
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
retval = _setsockname(siptr, name,
|
||||
_s_min(namelen, siptr->udata.addrsize));
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
return (retval);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
_setsockname(siptr, name, namelen)
|
||||
register struct _si_user *siptr;
|
||||
register struct sockaddr *name;
|
||||
register int namelen;
|
||||
{
|
||||
sigset_t procmask;
|
||||
|
||||
_s_blockallsignals(&procmask);
|
||||
if (!_s_do_ioctl(siptr->fd, (caddr_t)name, namelen,
|
||||
SI_SETMYNAME, NULL)) {
|
||||
_s_restoresigmask(&procmask);
|
||||
return (-1);
|
||||
}
|
||||
_s_restoresigmask(&procmask);
|
||||
|
||||
return (0);
|
||||
}
|
||||
138
lib/libsocket/socket/setsockopt.c
Executable file
138
lib/libsocket/socket/setsockopt.c
Executable file
@@ -0,0 +1,138 @@
|
||||
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
|
||||
/* All Rights Reserved */
|
||||
|
||||
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
|
||||
/* The copyright notice above does not evidence any */
|
||||
/* actual or intended publication of such source code. */
|
||||
|
||||
#ident "@(#)setsockopt.c 1.11 93/09/30 SMI" /* SVr4.0 1.6 */
|
||||
|
||||
/*
|
||||
* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
* PROPRIETARY NOTICE (Combined)
|
||||
*
|
||||
* This source code is unpublished proprietary information
|
||||
* constituting, or derived under license from AT&T's UNIX(r) System V.
|
||||
* In addition, portions of such source code were derived from Berkeley
|
||||
* 4.3 BSD under license from the Regents of the University of
|
||||
* California.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Copyright Notice
|
||||
*
|
||||
* Notice of copyright on this source code product does not indicate
|
||||
* publication.
|
||||
*
|
||||
* (c) 1986,1987,1988.1989 Sun Microsystems, Inc
|
||||
* (c) 1983,1984,1985,1986,1987,1988,1989 AT&T.
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "sockmt.h"
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stream.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <stropts.h>
|
||||
#include <sys/tihdr.h>
|
||||
#include <sys/timod.h>
|
||||
#include <sys/socket.h>
|
||||
#include <tiuser.h>
|
||||
#include <sys/sockmod.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "sock.h"
|
||||
|
||||
#pragma weak setsockopt = _setsockopt
|
||||
|
||||
int
|
||||
_setsockopt(s, level, optname, optval, optlen)
|
||||
register int s;
|
||||
register int level;
|
||||
register int optname;
|
||||
register char *optval;
|
||||
register int optlen;
|
||||
{
|
||||
register struct _si_user *siptr;
|
||||
sigset_t mask;
|
||||
int retval;
|
||||
|
||||
if ((siptr = _s_checkfd(s)) == NULL)
|
||||
return (-1);
|
||||
|
||||
MUTEX_LOCK_SIGMASK(&siptr->lock, mask);
|
||||
retval = __setsockopt(siptr, level, optname, optval, optlen);
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
return (retval);
|
||||
}
|
||||
|
||||
int
|
||||
__setsockopt(siptr, level, optname, optval, optlen)
|
||||
struct _si_user *siptr;
|
||||
register int level;
|
||||
register int optname;
|
||||
register char *optval;
|
||||
register int optlen;
|
||||
{
|
||||
register struct T_optmgmt_req *opt_req;
|
||||
register int s;
|
||||
char *cbuf;
|
||||
sigset_t procmask;
|
||||
register int size;
|
||||
register struct opthdr *opt;
|
||||
int didalloc = 0;
|
||||
|
||||
s = siptr->fd;
|
||||
|
||||
if (siptr->ctlbuf) {
|
||||
cbuf = siptr->ctlbuf;
|
||||
siptr->ctlbuf = NULL;
|
||||
} else {
|
||||
/*
|
||||
* siptr->ctlbuf is in use
|
||||
* allocate and free after use.
|
||||
*/
|
||||
if (_s_cbuf_alloc(siptr, &cbuf) < 0)
|
||||
return (-1);
|
||||
didalloc = 1;
|
||||
}
|
||||
opt_req = (struct T_optmgmt_req *)cbuf;
|
||||
opt_req->PRIM_type = T_OPTMGMT_REQ;
|
||||
opt_req->OPT_length = sizeof (*opt) + optlen;
|
||||
opt_req->OPT_offset = sizeof (*opt_req);
|
||||
opt_req->MGMT_flags = T_NEGOTIATE;
|
||||
|
||||
opt = (struct opthdr *)(cbuf + sizeof (*opt_req));
|
||||
opt->level = level;
|
||||
opt->name = optname;
|
||||
opt->len = optlen;
|
||||
(void) memcpy((caddr_t)opt + sizeof (*opt), optval, optlen);
|
||||
|
||||
size = opt_req->OPT_offset + opt_req->OPT_length;
|
||||
|
||||
_s_blockallsignals(&procmask);
|
||||
if (!_s_do_ioctl(s, cbuf, size, TI_OPTMGMT, 0)) {
|
||||
_s_restoresigmask(&procmask);
|
||||
if (didalloc)
|
||||
free(cbuf);
|
||||
else
|
||||
siptr->ctlbuf = cbuf;
|
||||
|
||||
return (-1);
|
||||
}
|
||||
_s_restoresigmask(&procmask);
|
||||
/* Catch changes to SO_DEBUG to make socket library tracing work */
|
||||
if (level == SOL_SOCKET && optname == SO_DEBUG)
|
||||
(void) _s_synch(siptr);
|
||||
|
||||
if (didalloc)
|
||||
free(cbuf);
|
||||
else
|
||||
siptr->ctlbuf = cbuf;
|
||||
return (0);
|
||||
}
|
||||
107
lib/libsocket/socket/shutdown.c
Executable file
107
lib/libsocket/socket/shutdown.c
Executable file
@@ -0,0 +1,107 @@
|
||||
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
|
||||
/* All Rights Reserved */
|
||||
|
||||
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
|
||||
/* The copyright notice above does not evidence any */
|
||||
/* actual or intended publication of such source code. */
|
||||
|
||||
#ident "@(#)shutdown.c 1.10 93/09/30 SMI" /* SVr4.0 1.7 */
|
||||
|
||||
/*
|
||||
* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
* PROPRIETARY NOTICE (Combined)
|
||||
*
|
||||
* This source code is unpublished proprietary information
|
||||
* constituting, or derived under license from AT&T's UNIX(r) System V.
|
||||
* In addition, portions of such source code were derived from Berkeley
|
||||
* 4.3 BSD under license from the Regents of the University of
|
||||
* California.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Copyright Notice
|
||||
*
|
||||
* Notice of copyright on this source code product does not indicate
|
||||
* publication.
|
||||
*
|
||||
* (c) 1986,1987,1988.1989 Sun Microsystems, Inc
|
||||
* (c) 1983,1984,1985,1986,1987,1988,1989 AT&T.
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "sockmt.h"
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stream.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <stropts.h>
|
||||
#include <sys/tihdr.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/socket.h>
|
||||
#include <tiuser.h>
|
||||
#include <sys/sockmod.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "sock.h"
|
||||
|
||||
#pragma weak shutdown = _shutdown
|
||||
|
||||
int
|
||||
_shutdown(s, how)
|
||||
register int s;
|
||||
int how;
|
||||
{
|
||||
sigset_t procmask;
|
||||
struct _si_user *siptr;
|
||||
sigset_t mask;
|
||||
|
||||
if ((siptr = _s_checkfd(s)) == (struct _si_user *)NULL)
|
||||
return (-1);
|
||||
|
||||
MUTEX_LOCK_SIGMASK(&siptr->lock, mask);
|
||||
if (how < 0 || how > 2) {
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if ((siptr->udata.so_state & SS_ISCONNECTED) == 0) {
|
||||
if (_s_synch(siptr) < 0) {
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
return (-1);
|
||||
}
|
||||
if ((siptr->udata.so_state & SS_ISCONNECTED) == 0) {
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
errno = ENOTCONN;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
_s_blockallsignals(&procmask);
|
||||
if (!_s_do_ioctl(s, (char *)&how, sizeof (how), SI_SHUTDOWN, 0)) {
|
||||
if (errno != EPIPE) {
|
||||
_s_restoresigmask(&procmask);
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
return (-1);
|
||||
} else errno = 0;
|
||||
}
|
||||
_s_restoresigmask(&procmask);
|
||||
|
||||
/*
|
||||
* If we got EPIPE back from the ioctl, then we can
|
||||
* no longer talk to sockmod. The best we can do now
|
||||
* is set our local state and hope the user doesn't
|
||||
* use read/write.
|
||||
*/
|
||||
if (how == 0 || how == 2)
|
||||
siptr->udata.so_state |= SS_CANTRCVMORE;
|
||||
if (how == 1 || how == 2)
|
||||
siptr->udata.so_state |= SS_CANTSENDMORE;
|
||||
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
return (0);
|
||||
}
|
||||
66
lib/libsocket/socket/sock.h
Executable file
66
lib/libsocket/socket/sock.h
Executable file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 1993 by Sun Microsystems, Inc
|
||||
*/
|
||||
|
||||
#pragma ident "@(#)sock.h 1.4 94/04/15 SMI"
|
||||
|
||||
|
||||
int __accept(struct _si_user *siptr, struct sockaddr *addr,
|
||||
int *addrlen, sigset_t *accmaskp);
|
||||
int __bind(struct _si_user *siptr, struct sockaddr *name,
|
||||
int namelen, char *raddr, int *raddrlen);
|
||||
|
||||
int __getpeername(struct _si_user *siptr, struct sockaddr *name, int *namelen);
|
||||
int __getsockname(struct _si_user *siptr, struct sockaddr *name, int *namelen);
|
||||
|
||||
int __setsockopt(struct _si_user *siptr, int level, int optname,
|
||||
char *optval, int optlen);
|
||||
|
||||
int _connect2(struct _si_user *siptr, struct t_call *sndcall,
|
||||
sigset_t *connmaskp);
|
||||
|
||||
|
||||
void _s_aligned_copy(char *buf, int len, int init_offset,
|
||||
char *datap, int *rtn_offset);
|
||||
struct _si_user *_s_checkfd(int fd);
|
||||
void _s_close(struct _si_user *siptr);
|
||||
int _s_cpaddr(struct _si_user *siptr, char *to, int tolen,
|
||||
char *from, int fromlen);
|
||||
int _s_do_ioctl(int fd, char *buf, int size, int cmd, int *retlen);
|
||||
int _s_is_ok(struct _si_user *siptr, long type, struct strbuf *ctlbufp);
|
||||
int _s_min(int x, int y);
|
||||
int _s_max(int x, int y);
|
||||
int _s_rcv_conn_con(struct _si_user *siptr, struct strbuf *ctlbufp);
|
||||
int _s_snd_conn_req(struct _si_user *siptr, struct t_call *call,
|
||||
struct strbuf *ctlbufp);
|
||||
int _s_soreceivexx(struct _si_user *siptr, int flags, char *buf, int len,
|
||||
struct sockaddr *from, int *fromlen,
|
||||
char *accrights, int *accrightslen,
|
||||
sigset_t *rcvmaskp);
|
||||
int _s_sosendxx(struct _si_user *siptr, int flags, char *buf, int len,
|
||||
struct sockaddr *to, int tolen,
|
||||
char *accrights, int accrightslen,
|
||||
sigset_t *sndmaskp);
|
||||
int _s_synch(struct _si_user *);
|
||||
int _s_uxpathlen(struct sockaddr_un *un);
|
||||
|
||||
struct _si_user *find_silink(int fd);
|
||||
int s_getfflags(struct _si_user *);
|
||||
void s_invalfflags(struct _si_user *);
|
||||
|
||||
/*
|
||||
* Socket library debugging
|
||||
*/
|
||||
extern int _s_sockdebug;
|
||||
#ifdef SOCKDEBUG
|
||||
#undef SOCKDEBUG
|
||||
#endif
|
||||
#ifdef lint
|
||||
#define SOCKDEBUG(S, A, B)
|
||||
#else
|
||||
#define SOCKDEBUG(S, A, B) \
|
||||
if ((((S) && (S)->udata.so_options & SO_DEBUG)) || \
|
||||
_s_sockdebug) { \
|
||||
(void) _syslog(LOG_ERR, (A), (B)); \
|
||||
}
|
||||
#endif
|
||||
70
lib/libsocket/socket/socket.c
Executable file
70
lib/libsocket/socket/socket.c
Executable file
@@ -0,0 +1,70 @@
|
||||
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
|
||||
/* All Rights Reserved */
|
||||
|
||||
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
|
||||
/* The copyright notice above does not evidence any */
|
||||
/* actual or intended publication of such source code. */
|
||||
|
||||
#ident "@(#)socket.c 1.8 93/09/30 SMI" /* SVr4.0 1.8 */
|
||||
|
||||
/*
|
||||
* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
* PROPRIETARY NOTICE (Combined)
|
||||
*
|
||||
* This source code is unpublished proprietary information
|
||||
* constituting, or derived under license from AT&T's UNIX(r) System V.
|
||||
* In addition, portions of such source code were derived from Berkeley
|
||||
* 4.3 BSD under license from the Regents of the University of
|
||||
* California.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Copyright Notice
|
||||
*
|
||||
* Notice of copyright on this source code product does not indicate
|
||||
* publication.
|
||||
*
|
||||
* (c) 1986,1987,1988.1989 Sun Microsystems, Inc
|
||||
* (c) 1983,1984,1985,1986,1987,1988,1989 AT&T.
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "sockmt.h"
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stream.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <stropts.h>
|
||||
#include <sys/tihdr.h>
|
||||
#include <sys/socket.h>
|
||||
#include <tiuser.h>
|
||||
#include <sys/sockmod.h>
|
||||
#include <signal.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "sock.h"
|
||||
|
||||
#pragma weak socket = _socket
|
||||
|
||||
int
|
||||
_socket(family, type, protocol)
|
||||
register int family;
|
||||
register int type;
|
||||
register int protocol;
|
||||
{
|
||||
register struct _si_user *siptr;
|
||||
|
||||
/*
|
||||
* Do common socket creation
|
||||
*/
|
||||
siptr = _s_socreate(family, type, protocol);
|
||||
|
||||
if (siptr == NULL)
|
||||
return (-1);
|
||||
|
||||
return (siptr->fd);
|
||||
}
|
||||
229
lib/libsocket/socket/socketpair.c
Executable file
229
lib/libsocket/socket/socketpair.c
Executable file
@@ -0,0 +1,229 @@
|
||||
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
|
||||
/* All Rights Reserved */
|
||||
|
||||
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
|
||||
/* The copyright notice above does not evidence any */
|
||||
/* actual or intended publication of such source code. */
|
||||
|
||||
#ident "@(#)socketpair.c 1.15 94/04/08 SMI" /* SVr4.0 1.11 */
|
||||
|
||||
/*
|
||||
* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
* PROPRIETARY NOTICE (Combined)
|
||||
*
|
||||
* This source code is unpublished proprietary information
|
||||
* constituting, or derived under license from AT&T's UNIX(r) System V.
|
||||
* In addition, portions of such source code were derived from Berkeley
|
||||
* 4.3 BSD under license from the Regents of the University of
|
||||
* California.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Copyright Notice
|
||||
*
|
||||
* Notice of copyright on this source code product does not indicate
|
||||
* publication.
|
||||
*
|
||||
* (c) 1986,1987,1988.1989 Sun Microsystems, Inc
|
||||
* (c) 1983,1984,1985,1986,1987,1988,1989 AT&T.
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "sockmt.h"
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stream.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <stropts.h>
|
||||
#include <sys/tihdr.h>
|
||||
#include <sys/socket.h>
|
||||
#include <tiuser.h>
|
||||
#include <sys/sockmod.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/poll.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "sock.h"
|
||||
|
||||
#pragma weak socketpair = _socketpair
|
||||
|
||||
int
|
||||
_socketpair(family, type, protocol, sv)
|
||||
register int family;
|
||||
register int type;
|
||||
register int protocol;
|
||||
register int sv[2];
|
||||
|
||||
{
|
||||
register struct _si_user *siptr;
|
||||
register struct _si_user *nsiptr;
|
||||
struct bind_ux bind_ux;
|
||||
struct bind_ux nbind_ux;
|
||||
struct t_call sndcall;
|
||||
int size;
|
||||
sigset_t mask;
|
||||
int saved_errno;
|
||||
|
||||
|
||||
if (family != AF_UNIX) {
|
||||
errno = EPROTONOSUPPORT;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create endpoints ns and s
|
||||
*/
|
||||
nsiptr = _s_socreate(family, type, protocol);
|
||||
siptr = _s_socreate(family, type, protocol);
|
||||
|
||||
if (nsiptr == NULL || siptr == NULL)
|
||||
return (-1);
|
||||
|
||||
(void) memset((caddr_t)&nbind_ux, 0, sizeof (nbind_ux));
|
||||
(void) memset((caddr_t)&bind_ux, 0, sizeof (bind_ux));
|
||||
(void) memset((caddr_t)&sndcall, 0, sizeof (sndcall));
|
||||
|
||||
/*
|
||||
* Bind each end.
|
||||
*/
|
||||
MUTEX_LOCK_SIGMASK(&nsiptr->lock, mask);
|
||||
size = sizeof (nbind_ux);
|
||||
if (__bind(nsiptr, NULL, 0, (caddr_t)&nbind_ux, &size) < 0) {
|
||||
MUTEX_UNLOCK_SIGMASK(&nsiptr->lock, mask);
|
||||
goto bad;
|
||||
}
|
||||
MUTEX_UNLOCK_SIGMASK(&nsiptr->lock, mask);
|
||||
if (size != sizeof (nbind_ux)) {
|
||||
errno = EPROTO;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
MUTEX_LOCK_SIGMASK(&siptr->lock, mask);
|
||||
if (__bind(siptr, NULL, 0, (caddr_t)&bind_ux, &size) < 0) {
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
goto bad;
|
||||
}
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
if (size != sizeof (nbind_ux)) {
|
||||
errno = EPROTO;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (type == SOCK_DGRAM) {
|
||||
/*
|
||||
* connect s->ns
|
||||
*/
|
||||
sndcall.addr.buf = (caddr_t)&nbind_ux;
|
||||
sndcall.addr.len = sizeof (nbind_ux);
|
||||
MUTEX_LOCK_SIGMASK(&siptr->lock, mask);
|
||||
if (_connect2(siptr, &sndcall, &mask) < 0) {
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
goto bad;
|
||||
}
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
|
||||
/*
|
||||
* connect ns->s
|
||||
*/
|
||||
sndcall.addr.buf = (caddr_t)&bind_ux;
|
||||
sndcall.addr.len = sizeof (bind_ux);
|
||||
MUTEX_LOCK_SIGMASK(&nsiptr->lock, mask);
|
||||
if (_connect2(nsiptr, &sndcall, &mask) < 0) {
|
||||
MUTEX_UNLOCK_SIGMASK(&nsiptr->lock, mask);
|
||||
goto bad;
|
||||
}
|
||||
MUTEX_UNLOCK_SIGMASK(&nsiptr->lock, mask);
|
||||
|
||||
/*
|
||||
* return descripters for each end
|
||||
*/
|
||||
sv[0] = nsiptr->fd;
|
||||
sv[1] = siptr->fd;
|
||||
|
||||
return (0);
|
||||
} else {
|
||||
int s2;
|
||||
int cntlflag;
|
||||
struct pollfd pfd[1];
|
||||
|
||||
/*
|
||||
* Set the queue length on s.
|
||||
*/
|
||||
if (_listen(siptr->fd, 1) < 0)
|
||||
goto bad;
|
||||
/*
|
||||
* Set ns no delay mode.
|
||||
*/
|
||||
cntlflag = s_getfflags(nsiptr);
|
||||
if ((cntlflag & O_NDELAY) == 0) {
|
||||
(void) _fcntl(nsiptr->fd, F_SETFL,
|
||||
(cntlflag | O_NDELAY) & ~O_NONBLOCK);
|
||||
nsiptr->fflags = (cntlflag | O_NDELAY) & ~O_NONBLOCK;
|
||||
}
|
||||
/*
|
||||
* Send the connect ns->s.
|
||||
*/
|
||||
sndcall.addr.buf = (caddr_t)&bind_ux;
|
||||
sndcall.addr.len = sizeof (bind_ux);
|
||||
MUTEX_LOCK_SIGMASK(&nsiptr->lock, mask);
|
||||
if (_connect2(nsiptr, &sndcall, &mask) < 0 &&
|
||||
errno != EINPROGRESS) {
|
||||
MUTEX_UNLOCK_SIGMASK(&nsiptr->lock, mask);
|
||||
goto bad;
|
||||
}
|
||||
MUTEX_UNLOCK_SIGMASK(&nsiptr->lock, mask);
|
||||
|
||||
/*
|
||||
* Pick up the connect indication on s2
|
||||
*/
|
||||
MUTEX_LOCK_SIGMASK(&siptr->lock, mask);
|
||||
if ((s2 = __accept(siptr, NULL, NULL, &mask)) < 0) {
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
goto bad;
|
||||
}
|
||||
MUTEX_UNLOCK_SIGMASK(&siptr->lock, mask);
|
||||
|
||||
/*
|
||||
* Wait at most 5 seconds for the
|
||||
* confirmation to arrive
|
||||
*/
|
||||
pfd[0].events = POLLOUT;
|
||||
pfd[0].fd = nsiptr->fd;
|
||||
pfd[0].revents = 0;
|
||||
if (poll(pfd, (u_long)1, 5*1000) < 0 ||
|
||||
pfd[0].revents != POLLOUT) {
|
||||
if (pfd[0].revents == 0)
|
||||
errno = ETIMEDOUT;
|
||||
else errno = ECONNABORTED;
|
||||
(void) close(s2);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset the O_NDELAY flag if necessary.
|
||||
*/
|
||||
if ((cntlflag & O_NDELAY) == 0) {
|
||||
(void) _fcntl(nsiptr->fd, F_SETFL, cntlflag);
|
||||
nsiptr->fflags = cntlflag;
|
||||
}
|
||||
sv[0] = nsiptr->fd;
|
||||
sv[1] = s2;
|
||||
|
||||
_s_close(siptr);
|
||||
|
||||
return (0);
|
||||
}
|
||||
bad:
|
||||
saved_errno = errno;
|
||||
|
||||
_s_close(nsiptr);
|
||||
_s_close(siptr);
|
||||
|
||||
errno = saved_errno;
|
||||
return (-1);
|
||||
}
|
||||
63
lib/libsocket/socket/sockmt.h
Executable file
63
lib/libsocket/socket/sockmt.h
Executable file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc
|
||||
*/
|
||||
|
||||
#pragma ident "@(#)sockmt.h 1.9 94/06/03 SMI"
|
||||
|
||||
#include <synch.h>
|
||||
#include <thread.h>
|
||||
|
||||
#ifdef _REENTRANT
|
||||
#define MUTEX_LOCK_SIGMASK(lock, oldmask) \
|
||||
{ sigset_t newmask; \
|
||||
(void) _sigfillset(&newmask); \
|
||||
_thr_sigsetmask(SIG_SETMASK, &newmask, &(oldmask)); \
|
||||
_mutex_lock(lock); \
|
||||
}
|
||||
|
||||
#define MUTEX_UNLOCK_SIGMASK(lock, oldmask) \
|
||||
{ sigset_t tmpmask; \
|
||||
_mutex_unlock(lock); \
|
||||
_thr_sigsetmask(SIG_SETMASK, &(oldmask), &tmpmask); \
|
||||
}
|
||||
#define MUTEX_LOCK_PROCMASK(lock, oldmask) \
|
||||
{ sigset_t newmask; \
|
||||
(void) _sigfillset(&newmask); \
|
||||
(void) _sigprocmask(SIG_SETMASK, &newmask, &(oldmask)); \
|
||||
_mutex_lock(lock); \
|
||||
}
|
||||
|
||||
#define MUTEX_UNLOCK_PROCMASK(lock, oldmask) \
|
||||
{ sigset_t tmpmask; \
|
||||
_mutex_unlock(lock); \
|
||||
(void) _sigprocmask(SIG_SETMASK, &(oldmask), &tmpmask); \
|
||||
}
|
||||
|
||||
#else /* _REENTRANT */
|
||||
|
||||
#define MUTEX_LOCK_SIGMASK(lock, oldmask)
|
||||
#define MUTEX_UNLOCK_SIGMASK(lock, oldmask)
|
||||
#define MUTEX_LOCK_PROCMASK(lock, oldmask) \
|
||||
{ sigset_t newmask; \
|
||||
(void) _sigfillset(&newmask); \
|
||||
(void) _sigprocmask(SIG_SETMASK, &newmask, &(oldmask)); \
|
||||
}
|
||||
|
||||
#define MUTEX_UNLOCK_PROCMASK(lock, oldmask) \
|
||||
{ sigset_t tmpmask; \
|
||||
(void) _sigprocmask(SIG_SETMASK, &(oldmask), &tmpmask); \
|
||||
}
|
||||
|
||||
|
||||
#endif /* _REENTRANT */
|
||||
|
||||
#ifdef lint
|
||||
#define _thr_sigsetmask(how, set, oset) thr_sigsetmask(how, set, oset)
|
||||
#define _mutex_lock(m) mutex_lock(m)
|
||||
#define _mutex_unlock(m) mutex_unlock(m)
|
||||
#define _ioctl(fd, req, arg) ioctl(fd, req, arg)
|
||||
#define _mknod(path, mode, dev) mknod(path, mode, dev)
|
||||
#define _stat(path, buf) stat(path, buf)
|
||||
#define _fcntl(fd, cmd, arg) fcntl(fd, cmd, arg)
|
||||
#define _listen(fd, count) listen(fd, count)
|
||||
#endif /* lint */
|
||||
Reference in New Issue
Block a user