/* uipc_syscalls.c 4.11 81/12/09 */
#include "../h/protosw.h"
#include "../h/socketvar.h"
#include "../net/in_systm.h"
* Socket system call interface.
* These routines interface the socket routines to UNIX,
* isolating the system interface from the socket-protocol interface.
static struct sockproto localproto
= { PF_UNIX
, 0 };
* Pipe system call interface.
register struct file
*rf
, *wf
;
struct socket
*rso
, *wso
;
u
.u_error
= socreate(&rso
, SOCK_STREAM
,
&localproto
, (struct sockaddr
*)0, 0);
u
.u_error
= socreate(&wso
, SOCK_STREAM
,
&localproto
, (struct sockaddr
*)0, 0);
rf
->f_flag
= FREAD
|FSOCKET
;
wf
->f_flag
= FWRITE
|FSOCKET
;
u
.u_r
.r_val2
= u
.u_r
.r_val1
;
if (piconnect(wso
, rso
) == 0)
u
.u_ofile
[u
.u_r
.r_val1
] = 0;
wso
->so_state
|= SS_USERGONE
;
rso
->so_state
|= SS_USERGONE
;
* Splice system call interface.
} *ap
= (struct a
*)u
.u_ap
;
if ((f1
->f_flag
& FSOCKET
) == 0 || (f2
->f_flag
& FSOCKET
) == 0) {
if (f1
->f_count
> 1 || f2
->f_count
> 1) {
u
.u_error
= ETOOMANYREFS
;
u
.u_error
= sosplice(f1
->f_socket
, f2
->f_socket
);
* Socket system call interface. Copy sa arguments
* set up file descriptor and call internal socket
} *uap
= (struct a
*)u
.u_ap
;
register struct file
*fp
;
if ((fp
= falloc()) == NULL
)
fp
->f_flag
= FSOCKET
|FREAD
|FWRITE
;
if (uap
->asp
&& copyin((caddr_t
)uap
->asp
, (caddr_t
)&sp
, sizeof (sp
)) ||
uap
->asa
&& copyin((caddr_t
)uap
->asa
, (caddr_t
)&sa
, sizeof (sa
))) {
u
.u_error
= socreate(&so
, uap
->type
,
uap
->asp
? &sp
: 0, uap
->asa
? &sa
: 0, uap
->options
);
u
.u_ofile
[u
.u_r
.r_val1
] = 0;
* Accept system call interface.
} *uap
= (struct a
*)u
.u_ap
;
register struct file
*fp
;
if (uap
->asa
&& useracc((caddr_t
)uap
->asa
, sizeof (sa
), B_WRITE
)==0) {
if ((fp
->f_flag
& FSOCKET
) == 0) {
if ((so
->so_options
& SO_NBIO
) &&
(so
->so_state
& SS_CONNAWAITING
) == 0) {
u
.u_error
= soaccept(so
, &sa
);
/* deal with new file descriptor case */
* Connect socket to foreign peer; system call
* interface. Copy sa arguments and call internal routine.
} *uap
= (struct a
*)u
.u_ap
;
register struct file
*fp
;
register struct socket
*so
;
if (copyin((caddr_t
)uap
->a
, (caddr_t
)&sa
, sizeof (sa
))) {
if ((fp
->f_flag
& FSOCKET
) == 0) {
u
.u_error
= soconnect(so
, &sa
);
if ((so
->so_options
& SO_NBIO
) &&
(so
->so_state
& SS_ISCONNECTING
)) {
while ((so
->so_state
& SS_ISCONNECTING
) && so
->so_error
== 0)
sleep((caddr_t
)&so
->so_timeo
, PZERO
+1);
u
.u_error
= so
->so_error
;
* Disconnect socket from foreign peer; system call
* interface. Copy sa arguments and call internal routine.
} *uap
= (struct a
*)u
.u_ap
;
register struct file
*fp
;
register struct socket
*so
;
copyin((caddr_t
)uap
->asa
, (caddr_t
)&sa
, sizeof (sa
))) {
if ((fp
->f_flag
& FSOCKET
) == 0) {
u
.u_error
= sodisconnect(so
, uap
->asa
? &sa
: 0);
if ((so
->so_options
&SO_NBIO
) && (so
->so_state
&SS_ISDISCONNECTING
)) {
while ((so
->so_state
& SS_ISDISCONNECTING
) && so
->so_error
== 0)
sleep((caddr_t
)&so
->so_timeo
, PZERO
+1);
u
.u_error
= so
->so_error
;
} *uap
= (struct a
*)u
.u_ap
;
register struct file
*fp
;
if ((fp
->f_flag
& FSOCKET
) == 0) {
if (useracc(uap
->cbuf
, uap
->count
, B_READ
) == 0 ||
uap
->asa
&& copyin((caddr_t
)uap
->asa
, (caddr_t
)&sa
, sizeof (sa
))) {
u
.u_error
= sosend(fp
->f_socket
, uap
->asa
? &sa
: 0);
u
.u_r
.r_val1
= uap
->count
- u
.u_count
;
* Receive data on socket.
} *uap
= (struct a
*)u
.u_ap
;
register struct file
*fp
;
if ((fp
->f_flag
& FSOCKET
) == 0) {
if (useracc(uap
->cbuf
, uap
->count
, B_WRITE
) == 0 ||
uap
->asa
&& copyin((caddr_t
)uap
->asa
, (caddr_t
)&sa
, sizeof (sa
))) {
u
.u_error
= soreceive(fp
->f_socket
, uap
->asa
? &sa
: 0);
(void) copyout((caddr_t
)&sa
, (caddr_t
)uap
->asa
, sizeof (sa
));
u
.u_r
.r_val1
= uap
->count
- u
.u_count
;
} *uap
= (struct a
*)u
.u_ap
;
register struct file
*fp
;
if ((fp
->f_flag
& FSOCKET
) == 0) {
if (copyout((caddr_t
)&fp
->f_socket
->so_addr
, (caddr_t
)uap
->asa
,
sizeof (struct sockaddr
))) {