/* uipc_usrreq.c 1.2 82/11/03 */
#include "../h/protosw.h"
#include "../h/socketvar.h"
* Unix communications domain.
uipc_usrreq(so
, req
, m
, nam
, opt
)
struct unpcb
*unp
= sotounpcb(so
);
register struct socket
*so2
;
if (unp
== 0 && req
!= PRU_ATTACH
)
return (EINVAL
); /* XXX */
error
= unp_connect(so
, nam
);
struct sockaddr_un
*soun
= mtod(nam
, struct sockaddr_un
*);
bzero((caddr_t
)soun
, sizeof (*soun
));
soun
->sun_family
= AF_UNIX
;
#define rcv (&so->so_rcv)
#define snd (&so2->so_snd)
so2
= unp
->unp_conn
->unp_socket
;
* Transfer resources back to send port
* and wakeup any waiting to write.
snd
->sb_mbmax
+= rcv
->sb_mbmax
- rcv
->sb_mbcnt
;
rcv
->sb_mbmax
= rcv
->sb_mbcnt
;
snd
->sb_hiwat
+= rcv
->sb_hiwat
- rcv
->sb_cc
;
rcv
->sb_hiwat
= rcv
->sb_cc
;
error
= unp_connect(so
, nam
);
if (unp
->unp_conn
== 0) {
so2
= unp
->unp_conn
->unp_socket
;
if (sbspace(&so2
->so_rcv
) > 0) /* XXX */
sbappendaddr(so2
, m
, nam
); /* XXX */
#define rcv (&so2->so_rcv)
#define snd (&so->so_snd)
so2
= unp
->unp_conn
->unp_socket
;
* Send to paired receive port, and then
* give it enough resources to hold what it already has.
snd
->sb_mbmax
-= rcv
->sb_mbcnt
- rcv
->sb_mbmax
;
rcv
->sb_mbmax
= rcv
->sb_mbcnt
;
snd
->sb_hiwat
-= rcv
->sb_cc
- rcv
->sb_hiwat
;
rcv
->sb_hiwat
= rcv
->sb_cc
;
unp_drop(unp
, ECONNABORTED
);
/* SOME AS YET UNIMPLEMENTED HOOKS */
/* END UNIMPLEMENTED HOOKS */
int unp_sendspace
= 1024*2;
int unp_recvspace
= 1024*2;
struct sockaddr_un
*soun
;
register struct unpcb
*unp
;
error
= soreserve(so
, unp_sendspace
, unp_recvspace
);
m
= m_getclr(M_DONTWAIT
);
unp
= mtod(m
, struct unpcb
*);
so
->so_pcb
= (caddr_t
)unp
;
error
= unp_bind(unp
, soun
);
register struct unpcb
*unp2
= unp
->unp_conn
;
soisdisconnected(unp
->unp_socket
);
switch (unp
->unp_socket
->so_type
) {
if (unp2
->unp_refs
== unp
)
unp2
->unp_refs
= unp
->unp_nextref
;
if (unp2
->unp_nextref
== unp
)
unp2
= unp2
->unp_nextref
;
unp2
->unp_nextref
= unp
->unp_nextref
;
soisdisconnected(unp2
->unp_socket
);
unp_drop(unp2
, ECONNRESET
);
unp_drop(unp
->unp_refs
, ECONNRESET
);
soisdisconnected(unp
->unp_socket
);
unp
->unp_socket
->so_pcb
= 0;
register struct socket
*so
= unp
->unp_socket
;
#ifdef sometimes /* ??? */
soisdisconnected(unp
->unp_socket
);
unp
->unp_socket
->so_error
= errno
;
struct sockaddr_un
*soun
;
register struct inode
*ip
;
u
.u_dirp
= soun
->sun_path
;
soun
->sun_path
[sizeof(soun
->sun_path
)-1] = 0;
ip
= maknode(IFSOCK
| 0777);
error
= u
.u_error
; /* XXX */
ip
->i_socket
= unp
->unp_socket
;
iunlock(ip
); /* but keep reference */
struct sockaddr_un
*soun
;
u
.u_dirp
= soun
->sun_path
;
soun
->sun_path
[sizeof(soun
->sun_path
)-1] = 0;
error
= unp_connectip(so
, ip
);
struct unpcb
*unp
= sotounpcb(so
);
struct socket
*so2
, *so3
;
if ((ip
->i_mode
&IFMT
) != IFSOCK
) {
if (so2
->so_type
!= so
->so_type
) {
unp
->unp_conn
= sotounpcb(so2
);
unp
->unp_nextref
= unp2
->unp_refs
;
if ((so2
->so_options
&SO_ACCEPTCONN
) == 0 ||
(so3
= sonewconn(so2
)) == 0) {
unp
->unp_conn
= sotounpcb(so3
);
soisconnected(unp
->unp_conn
->unp_socket
);