-/*
- * Disconnect socket from foreign peer; system call
- * interface. Copy sa arguments and call internal routine.
- */
-sdisconnect()
-{
- register struct a {
- int fdes;
- struct sockaddr *asa;
- } *uap = (struct a *)u.u_ap;
- struct sockaddr sa;
- register struct file *fp;
- register struct socket *so;
- int s;
-COUNT(SDISCONNECT);
-
- if (uap->asa &&
- copyin((caddr_t)uap->asa, (caddr_t)&sa, sizeof (sa))) {
- u.u_error = EFAULT;
- return;
- }
- fp = getf(uap->fdes);
- if (fp == 0)
- return;
- if ((fp->f_flag & FSOCKET) == 0) {
- u.u_error = ENOTSOCK;
- return;
- }
- so = fp->f_socket;
- u.u_error = sodisconnect(so, uap->asa ? &sa : 0);
- if (u.u_error)
- return;
- s = splnet();
- if ((so->so_options&SO_NONBLOCKING) && (so->so_state&SS_ISDISCONNECTING)) {
- u.u_error = EINPROGRESS;
- splx(s);
- return;
- }
- while ((so->so_state & SS_ISDISCONNECTING) && so->so_error == 0)
- sleep((caddr_t)&so->so_timeo, PZERO+1);
- u.u_error = so->so_error;
- so->so_error = 0;
- splx(s);
-}
-