From owner-p4-projects Wed Aug 14 18:46:43 2002 Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 9D8EB37B401; Wed, 14 Aug 2002 18:46:11 -0700 (PDT) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.FreeBSD.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 3F50037B400 for ; Wed, 14 Aug 2002 18:46:11 -0700 (PDT) Received: from freefall.freebsd.org (freefall.FreeBSD.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id CF78543E65 for ; Wed, 14 Aug 2002 18:46:10 -0700 (PDT) (envelope-from peter@freebsd.org) Received: from freefall.freebsd.org (perforce@localhost [127.0.0.1]) by freefall.freebsd.org (8.12.4/8.12.4) with ESMTP id g7F1kAJU095457 for ; Wed, 14 Aug 2002 18:46:10 -0700 (PDT) (envelope-from peter@freebsd.org) Received: (from perforce@localhost) by freefall.freebsd.org (8.12.4/8.12.4/Submit) id g7F1kA20095454 for perforce@freebsd.org; Wed, 14 Aug 2002 18:46:10 -0700 (PDT) Date: Wed, 14 Aug 2002 18:46:10 -0700 (PDT) Message-Id: <200208150146.g7F1kA20095454@freefall.freebsd.org> X-Authentication-Warning: freefall.freebsd.org: perforce set sender to peter@freebsd.org using -f From: Peter Wemm Subject: PERFORCE change 15992 for review To: Perforce Change Reviews Sender: owner-p4-projects@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG http://people.freebsd.org/~peter/p4db/chv.cgi?CH=15992 Change 15992 by peter@peter_daintree on 2002/08/14 18:45:14 Hmm. Another freshly spammed file. :-( Affected files ... .. //depot/projects/ia64/sys/kern/uipc_syscalls.c#17 integrate Differences ... ==== //depot/projects/ia64/sys/kern/uipc_syscalls.c#17 (text+ko) ==== @@ -937,170 +937,213 @@ len = MIN(len, fromsa->sa_len); #ifdef COMPAT_OLDSOCK if (mp->msg_flags & MSG_COMPAT) - ((struct osockaddr *)fromsa)->sa_famil Initial pass thru sops to see what permissions are needed. - * Also perform any checks that don't need repeating on each - * attempt to satisfy the request vector. - */ - j = 0; /* permission needed */ - do_undos = 0; - for (i = 0; i < nsops; i++) { - sopptr = &sops[i]; - if (sopptr->sem_num >= semaptr->sem_nsems) { - error = EFBIG; - goto done2; + ((struct osockaddr *)fromsa)->sa_family = + fromsa->sa_family; +#endif + error = copyout(fromsa, mp->msg_name, (unsigned)len); + if (error) + goto out; + } + mp->msg_namelen = len; + if (namelenp && + (error = copyout(&len, namelenp, sizeof (int)))) { +#ifdef COMPAT_OLDSOCK + if (mp->msg_flags & MSG_COMPAT) + error = 0; /* old recvfrom didn't check */ + else +#endif + goto out; } - if (sopptr->sem_flg & SEM_UNDO && sopptr->sem_op != 0) - do_undos = 1; - j |= (sopptr->sem_op == 0) ? SEM_R : SEM_A; } + if (mp->msg_control) { +#ifdef COMPAT_OLDSOCK + /* + * We assume that old recvmsg calls won't receive access + * rights and other control info, esp. as control info + * is always optional and those options didn't exist in 4.3. + * If we receive rights, trim the cmsghdr; anything else + * is tossed. + */ + if (control && mp->msg_flags & MSG_COMPAT) { + if (mtod(control, struct cmsghdr *)->cmsg_level != + SOL_SOCKET || + mtod(control, struct cmsghdr *)->cmsg_type != + SCM_RIGHTS) { + mp->msg_controllen = 0; + goto out; + } + control->m_len -= sizeof (struct cmsghdr); + control->m_data += sizeof (struct cmsghdr); + } +#endif + len = mp->msg_controllen; + m = control; + mp->msg_controllen = 0; + ctlbuf = mp->msg_control; - if ((error = ipcperm(td, &semaptr->sem_perm, j))) { - DPRINTF(("error = %d from ipaccess\n", error)); - goto done2; - } + while (m && len > 0) { + unsigned int tocopy; - /* - * Loop trying to satisfy the vector of requests. - * If we reach a point where we must wait, any requests already - * performed are rolled back and we go to sleep until some other - * process wakes us up. At this point, we start all over again. - * - * This ensures that from the perspective of other tasks, a set - * of requests is atomic (never partially satisfied). - */ - for (;;) { - do_wakeup = 0; - error = 0; /* error return if necessary */ + if (len >= m->m_len) + tocopy = m->m_len; + else { + mp->msg_flags |= MSG_CTRUNC; + tocopy = len; + } + + if ((error = copyout(mtod(m, caddr_t), + ctlbuf, tocopy)) != 0) + goto out; - for (i = 0; i < nsops; i++) { - sopptr = &sops[i]; - semptr = &semaptr->sem_base[sopptr->sem_num]; + ctlbuf += tocopy; + len -= tocopy; + m = m->m_next; + } + mp->msg_controllen = ctlbuf - (caddr_t)mp->msg_control; + } +out: + fputsock(so); + if (fromsa) + FREE(fromsa, M_SONAME); + if (control) + m_freem(control); + return (error); +} - DPRINTF(( - "semop: semaptr=%x, sem_base=%x, " - "semptr=%x, sem[%d]=%d : op=%d, flag=%s\n", - semaptr, semaptr->sem_base, semptr, - sopptr->sem_num, semptr->semval, sopptr->sem_op, - (sopptr->sem_flg & IPC_NOWAIT) ? - "nowait" : "wait")); +/* + * MPSAFE + */ +int +recvfrom(td, uap) + struct thread *td; + register struct recvfrom_args /* { + int s; + caddr_t buf; + size_t len; + int flags; + caddr_t from; + int *fromlenaddr; + } */ *uap; +{ + struct msghdr msg; + struct iovec aiov; + int error; - if (sopptr->sem_op < 0) { - if (semptr->semval + sopptr->sem_op < 0) { - DPRINTF(("semop: can't do it now\n")); - break; - } else { - semptr->semval += sopptr->sem_op; - if (semptr->semval == 0 && - semptr->semzcnt > 0) - do_wakeup = 1; - } - } else if (sopptr->sem_op == 0) { - if (semptr->semval != 0) { - DPRINTF(("semop: not zero now\n")); - break; - } - } else if (semptr->semval + sopptr->sem_op > - seminfo.semvmx) { - error = ERANGE; - break; - } else { - if (semptr->semncnt > 0) - do_wakeup = 1; - semptr->semval += sopptr->sem_op; - } - } + mtx_lock(&Giant); + if (uap->fromlenaddr) { + error = copyin(uap->fromlenaddr, + &msg.msg_namelen, sizeof (msg.msg_namelen)); + if (error) + goto done2; + } else { + msg.msg_namelen = 0; + } + msg.msg_name = uap->from; + msg.msg_iov = &aiov; + msg.msg_iovlen = 1; + aiov.iov_base = uap->buf; + aiov.iov_len = uap->len; + msg.msg_control = 0; + msg.msg_flags = uap->flags; + error = recvit(td, uap->s, &msg, uap->fromlenaddr); +done2: + mtx_unlock(&Giant); + return(error); +} - /* - * Did we get through the entire vector? - */ - if (i >= nsops) - goto done; +#ifdef COMPAT_OLDSOCK +/* + * MPSAFE + */ +int +orecvfrom(td, uap) + struct thread *td; + struct recvfrom_args *uap; +{ - /* - * No ... rollback anything that we've already done - */ - DPRINTF(("semop: rollback 0 through %d\n", i-1)); - for (j = 0; j < i; j++) - semaptr->sem_base[sops[j].sem_num].semval -= - sops[j].sem_op; + uap->flags |= MSG_COMPAT; + return (recvfrom(td, uap)); +} +#endif - /* If we detected an error, return it */ - if (error != 0) - goto done2; - /* - * If the request that we couldn't satisfy has the - * NOWAIT flag set then return with EAGAIN. - */ - if (sopptr->sem_flg & IPC_NOWAIT) { - error = EAGAIN; - goto done2; - } +#ifdef COMPAT_OLDSOCK +/* + * MPSAFE + */ +int +orecv(td, uap) + struct thread *td; + register struct orecv_args /* { + int s; + caddr_t buf; + int len; + int flags; + } */ *uap; +{ + struct msghdr msg; + struct iovec aiov; + int error; - if (sopptr->sem_op == 0) - semptr->semzcnt++; - else - semptr->semncnt++; + mtx_lock(&Giant); + msg.msg_name = 0; + msg.msg_namelen = 0; + msg.msg_iov = &aiov; + msg.msg_iovlen = 1; + aiov.iov_base = uap->buf; + aiov.iov_len = uap->len; + msg.msg_control = 0; + msg.msg_flags = uap->flags; + error = recvit(td, uap->s, &msg, NULL); + mtx_unlock(&Giant); + return (error); +} - DPRINTF(("semop: good night!\n")); - error = tsleep(semaptr, (PZERO - 4) | PCATCH, "semwait", 0); - DPRINTF(("semop: good morning (error=%d)!\n", error)); +/* + * Old recvmsg. This code takes advantage of the fact that the old msghdr + * overlays the new one, missing only the flags, and with the (old) access + * rights where the control fields are now. + * + * MPSAFE + */ +int +orecvmsg(td, uap) + struct thread *td; + register struct orecvmsg_args /* { + int s; + struct omsghdr *msg; + int flags; + } */ *uap; +{ + struct msghdr msg; + struct iovec aiov[UIO_SMALLIOV], *iov; + int error; - if (error != 0) { - error = EINTR; - goto done2; - } - DPRINTF(("semop: good morning!\n")); + error = copyin(uap->msg, &msg, sizeof (struct omsghdr)); + if (error) + return (error); - /* - * Make sure that the semaphore still exists - */ - if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0 || - semaptr->sem_perm.seq != IPCID_TO_SEQ(uap->semid)) { - error = EIDRM; + mtx_lock(&Giant); + if ((u_int)msg.msg_iovlen >= UIO_SMALLIOV) { + if ((u_int)msg.msg_iovlen >= UIO_MAXIOV) { + error = EMSGSIZE; goto done2; } - - /* - * The semaphore is still alive. Readjust the count of - * waiting processes. - */ - if (sopptr->sem_op == 0) - semptr->semzcnt--; - else - semptr->semncnt--; + MALLOC(iov, struct iovec *, + sizeof(struct iovec) * (u_int)msg.msg_iovlen, M_IOV, + M_WAITOK); + } else { + iov = aiov; } + msg.msg_flags = uap->flags | MSG_COMPAT; + error = copyin(msg.msg_iov, iov, + (unsigned)(msg.msg_iovlen * sizeof (struct iovec))); + if (error) + goto done; + msg.msg_iov = iov; + error = recvit(td, uap->s, &msg, &uap->msg->msg_namelen); -done: - /* - * Process any SEM_UNDO requests. - */ - if (do_undos) { - suptr = NULL; - for (i = 0; i < nsops; i++) { - /* - * We only need to deal with SEM_UNDO's for non-zero - * op's. - */ - int adjval; - - if ((sops[i].sem_flg & SEM_UNDO) == 0) - continue; - adjval = sops[i].sem_op; - if (adjval == 0) - continue; - error = semundo_adjust(td, &suptr, semid, - sops[i].sem_num, -adjval); - if (error == 0) - continue; - - /* - * Oh-Oh! We ran out of either sem_undo's or undo's. - * Rollback the adjustments to this point and then - * rollback the semaphore ups and down so we can return - * with an error with all structures restored. We - * rollback the undo's in the exact reverse order that - * we applied them. This gu0) + if (msg.msg_controllen && error == 0) error = copyout(&msg.msg_controllen, &uap->msg->msg_accrightslen, sizeof (int)); done: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe p4-projects" in the body of the message