/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/errno.h>
+#include <sys/syscall.h>
+
+#include <bsm/audit_kernel.h>
#include <net/if.h>
#include <net/route.h>
#if KTRACE
#include <sys/ktrace.h>
#endif
+#include <sys/vnode.h>
-static int dofileread __P((struct proc *, struct file *, int, void *,
- size_t, off_t, int, int*));
-static int dofilewrite __P((struct proc *, struct file *, int,
- const void *, size_t, off_t, int, int*));
-static struct file*
+__private_extern__ struct file*
holdfp(fdp, fd, flag)
struct filedesc* fdp;
int fd, flag;
(fp->f_flag & flag) == 0) {
return (NULL);
}
- fref(fp);
+ if (fref(fp) == -1)
+ return (NULL);
return (fp);
}
uap->offset, FOF_OFFSET, retval);
}
frele(fp);
+
+ if (!error)
+ KERNEL_DEBUG_CONSTANT((BSDDBG_CODE(DBG_BSD_SC_EXTENDED_INFO, SYS_pread) | DBG_FUNC_NONE),
+ uap->fd, uap->nbyte, (unsigned int)((uap->offset >> 32)), (unsigned int)(uap->offset), 0);
+
return(error);
}
/*
* Code common for read and pread
*/
-int
+__private_extern__ int
dofileread(p, fp, fd, buf, nbyte, offset, flags, retval)
struct proc *p;
struct file *fp;
uap->offset, FOF_OFFSET, retval);
}
frele(fp);
+
+ if (!error)
+ KERNEL_DEBUG_CONSTANT((BSDDBG_CODE(DBG_BSD_SC_EXTENDED_INFO, SYS_pwrite) | DBG_FUNC_NONE),
+ uap->fd, uap->nbyte, (unsigned int)((uap->offset >> 32)), (unsigned int)(uap->offset), 0);
+
return(error);
}
-static int
+__private_extern__ int
dofilewrite(p, fp, fd, buf, nbyte, offset, flags, retval)
struct proc *p;
struct file *fp;
if (auio.uio_resid != cnt && (error == ERESTART ||
error == EINTR || error == EWOULDBLOCK))
error = 0;
- if (error == EPIPE)
- psignal(p, SIGPIPE);
+ /* The socket layer handles SIGPIPE */
+ if (error == EPIPE && fp->f_type != DTYPE_SOCKET)
+ psignal(p, SIGPIPE);
}
cnt -= auio.uio_resid;
#if KTRACE
#define STK_PARAMS 128
char stkbuf[STK_PARAMS];
+ AUDIT_ARG(fd, uap->fd);
+ AUDIT_ARG(cmd, uap->com); /* XXX cmd is int, uap->com is long */
+ AUDIT_ARG(addr, uap->data);
if (error = fdgetf(p, uap->fd, &fp))
return (error);
+ AUDIT_ARG(file, p, fp);
if ((fp->f_flag & (FREAD | FWRITE)) == 0)
return (EBADF);
int nfunnel = 0;
int count, nfcount;
char * wql_ptr;
+ struct vnode *vp;
/*
* Problems when reboot; due to MacOSX signal probs
wql_ptr = (char *)0;
else
wql_ptr = (wql+ nc * SIZEOF_WAITQUEUE_LINK);
- if (fp->f_ops && (fp->f_type != DTYPE_SOCKET)
+ /*
+ * Merlot: need to remove the bogus f_data check
+ * from the following "if" statement. It's there
+ * because of various problems stemming from
+ * races due to the split-funnels and lack of real
+ * referencing on sockets...
+ */
+ if (fp->f_ops && (fp->f_type != DTYPE_SOCKET)
+ && (fp->f_data != (caddr_t)-1)
+ && !(fp->f_type == DTYPE_VNODE
+ && (vp = (struct vnode *)fp->f_data)
+ && vp->v_type == VFIFO)
&& fo_select(fp, flag[msk], wql_ptr, p)) {
optr[fd/NFDBITS] |= (1 << (fd % NFDBITS));
n++;
wql_ptr = (char *)0;
else
wql_ptr = (wql+ nc * SIZEOF_WAITQUEUE_LINK);
- if (fp->f_ops && (fp->f_type == DTYPE_SOCKET) &&
- fo_select(fp, flag[msk], wql_ptr, p)) {
+ if (fp->f_ops
+ && (fp->f_type == DTYPE_SOCKET
+ || (fp->f_type == DTYPE_VNODE
+ && (vp = (struct vnode *)fp->f_data)
+ && vp != (struct vnode *)-1
+ && vp->v_type == VFIFO))
+ && fo_select(fp, flag[msk], wql_ptr, p)) {
optr[fd/NFDBITS] |= (1 << (fd % NFDBITS));
n++;
}
static int flag[3] = { FREAD, FWRITE, 0 };
u_int32_t *iptr, *fptr, *fbits;
u_int nw;
+ struct vnode *vp;
/*
* Problems when reboot; due to MacOSX signal probs
*nfcount=0;
return(EBADF);
}
- if (fp->f_type == DTYPE_SOCKET)
+ if (fp->f_type == DTYPE_SOCKET ||
+ (fp->f_type == DTYPE_VNODE
+ && (vp = (struct vnode *)fp->f_data)
+ && vp->v_type == VFIFO))
nfc++;
n++;
}
}
if ((sip->si_flags & SI_INITED) == 0) {
- wait_queue_init(&sip->wait_queue, SYNC_POLICY_FIFO);
+ wait_queue_init(&sip->si_wait_queue, SYNC_POLICY_FIFO);
sip->si_flags |= SI_INITED;
sip->si_flags &= ~SI_CLEAR;
}
sip->si_flags &= ~SI_COLL;
sip->si_flags |= SI_RECORDED;
- if (!wait_queue_member(&sip->wait_queue, ut->uu_wqsub))
- wait_queue_link_noalloc(&sip->wait_queue, ut->uu_wqsub, (wait_queue_link_t)p_wql);
+ if (!wait_queue_member(&sip->si_wait_queue, ut->uu_wqsub))
+ wait_queue_link_noalloc(&sip->si_wait_queue, ut->uu_wqsub, (wait_queue_link_t)p_wql);
return;
}
}
if (sip->si_flags & SI_RECORDED) {
- wait_queue_wakeup_all(&sip->wait_queue, &selwait, THREAD_AWAKENED);
+ wait_queue_wakeup_all(&sip->si_wait_queue, &selwait, THREAD_AWAKENED);
sip->si_flags &= ~SI_RECORDED;
}
sip->si_flags &= ~(SI_RECORDED | SI_COLL);
}
sip->si_flags |= SI_CLEAR;
- wait_queue_unlinkall_nofree(&sip->wait_queue);
+ wait_queue_unlinkall_nofree(&sip->si_wait_queue);
}
}
if (interval != 0)
- clock_absolutetime_interval_to_deadline(interval, &abstime)
+ clock_absolutetime_interval_to_deadline(interval, &abstime);
KERNEL_DEBUG(DBG_MISC_WAIT, 1,&p->p_evlist,0,0,0);
error = tsleep1(&p->p_evlist, PSOCK | PCATCH,
return(EBADF);
if (fp->f_type != DTYPE_SOCKET) return(EINVAL); // for now must be sock
sp = (struct socket *)fp->f_data;
- assert(sp != NULL);
+ /* soo_close sets f_data to 0 before switching funnel */
+ if (sp == (struct socket *)0)
+ return(EBADF);
// locate event if possible
for (evq = sp->so_evlist.tqh_first;