This commit is contained in:
seta75D
2021-10-11 19:38:01 -03:00
commit 7c4988eac0
12567 changed files with 3198619 additions and 0 deletions

189
lib/libsocket/socket/_conn_util.c Executable file
View 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

File diff suppressed because it is too large Load Diff

378
lib/libsocket/socket/accept.c Executable file
View 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
View 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);
}

View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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);
}

View 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);
}

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