[BACK]Return to uipc_usrreq.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / kern

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sys/kern/uipc_usrreq.c between version 1.23 and 1.24

version 1.23, 1996/05/23 17:07:03 version 1.24, 1997/04/10 01:51:21
Line 1 
Line 1 
 /*      $NetBSD$        */  /*      $NetBSD$        */
   
 /*  /*
    * Copyright (c) 1997 Christopher G. Demetriou.  All rights reserved.
  * Copyright (c) 1982, 1986, 1989, 1991, 1993   * Copyright (c) 1982, 1986, 1989, 1991, 1993
  *      The Regents of the University of California.  All rights reserved.   *      The Regents of the University of California.  All rights reserved.
  *   *
Line 625  unp_externalize(rights)
Line 626  unp_externalize(rights)
         struct mbuf *rights;          struct mbuf *rights;
 {  {
         struct proc *p = curproc;               /* XXX */          struct proc *p = curproc;               /* XXX */
         register int i;  
         register struct cmsghdr *cm = mtod(rights, struct cmsghdr *);          register struct cmsghdr *cm = mtod(rights, struct cmsghdr *);
         register struct file **rp = (struct file **)(cm + 1);          register int i, *fdp = (int *)(cm + 1);
           register struct file **rp = (struct file **)ALIGN(cm + 1);
         register struct file *fp;          register struct file *fp;
         int newfds = (cm->cmsg_len - sizeof(*cm)) / sizeof (int);          int nfds = (cm->cmsg_len - ALIGN(sizeof(*cm))) / sizeof (struct file *);
         int f;          int f;
   
         if (!fdavail(p, newfds)) {          /* Make sure that the recipient has space */
                 for (i = 0; i < newfds; i++) {          if (!fdavail(p, nfds)) {
                   for (i = 0; i < nfds; i++) {
                         fp = *rp;                          fp = *rp;
                         unp_discard(fp);                          unp_discard(fp);
                         *rp++ = 0;                          *rp++ = 0;
                 }                  }
                 return (EMSGSIZE);                  return (EMSGSIZE);
         }          }
         for (i = 0; i < newfds; i++) {  
           /*
            * Add file to the recipient's open file table, converting them
            * to integer file descriptors as we go.  Done in forward order
            * because an integer will always come in the same place or before
            * its corresponding struct file pointer.
            */
           for (i = 0; i < nfds; i++) {
                 if (fdalloc(p, 0, &f))                  if (fdalloc(p, 0, &f))
                         panic("unp_externalize");                          panic("unp_externalize");
                 fp = *rp;                  fp = *rp;
                 p->p_fd->fd_ofiles[f] = fp;                  p->p_fd->fd_ofiles[f] = fp;
                 fp->f_msgcount--;                  fp->f_msgcount--;
                 unp_rights--;                  unp_rights--;
                 *(int *)rp++ = f;                  *fdp++ = f;
         }          }
   
           /*
            * Adjust length, in case of transition from large struct file
            * pointers to ints.
            */
           cm->cmsg_len = sizeof(*cm) + (nfds * sizeof(int));
           rights->m_len = cm->cmsg_len;
         return (0);          return (0);
 }  }
   
Line 657  unp_internalize(control, p)
Line 673  unp_internalize(control, p)
         struct mbuf *control;          struct mbuf *control;
         struct proc *p;          struct proc *p;
 {  {
         struct filedesc *fdp = p->p_fd;          struct filedesc *fdescp = p->p_fd;
         register struct cmsghdr *cm = mtod(control, struct cmsghdr *);          register struct cmsghdr *cm = mtod(control, struct cmsghdr *);
         register struct file **rp;          register struct file **rp;
         register struct file *fp;          register struct file *fp;
         register int i, fd;          register int i, fd, *fdp;
         int oldfds;          int nfds;
           u_int neededspace;
   
           /* Sanity check the control message header */
         if (cm->cmsg_type != SCM_RIGHTS || cm->cmsg_level != SOL_SOCKET ||          if (cm->cmsg_type != SCM_RIGHTS || cm->cmsg_level != SOL_SOCKET ||
             cm->cmsg_len != control->m_len)              cm->cmsg_len != control->m_len)
                 return (EINVAL);                  return (EINVAL);
         oldfds = (cm->cmsg_len - sizeof (*cm)) / sizeof (int);  
         rp = (struct file **)(cm + 1);          /* Verify that the file descriptors are valid */
         for (i = 0; i < oldfds; i++) {          nfds = (cm->cmsg_len - sizeof (*cm)) / sizeof (int);
                 fd = *(int *)rp++;          fdp = (int *)(cm + 1);
                 if ((unsigned)fd >= fdp->fd_nfiles ||          for (i = 0; i < nfds; i++) {
                     fdp->fd_ofiles[fd] == NULL)                  fd = *fdp++;
                   if ((unsigned)fd >= fdescp->fd_nfiles ||
                       fdescp->fd_ofiles[fd] == NULL)
                         return (EBADF);                          return (EBADF);
         }          }
         rp = (struct file **)(cm + 1);  
         for (i = 0; i < oldfds; i++) {          /* Make sure we have room for the struct file pointers */
                 fp = fdp->fd_ofiles[*(int *)rp];  morespace:
                 *rp++ = fp;          neededspace = (ALIGN(sizeof (*cm)) + nfds * sizeof (struct file *)) -
                   control->m_len;
           if (neededspace > M_TRAILINGSPACE(control)) {
   
                   /* if we already have a cluster, the message is just too big */
                   if (control->m_flags & M_EXT)
                           return (E2BIG);
   
                   /* allocate a cluster and try again */
                   MCLGET(control, M_WAIT);
                   if ((control->m_flags & M_EXT) == 0)
                           return (ENOBUFS);       /* allocation failed */
   
                   /* copy the data to the cluster */
                   bcopy(cm, mtod(control, char *), cm->cmsg_len);
                   cm = mtod(control, struct cmsghdr *);
                   goto morespace;
           }
   
           /* adjust message & mbuf to note amount of space actually used. */
           cm->cmsg_len += neededspace;
           control->m_len = cm->cmsg_len;
   
           /*
            * Transform the file descriptors into struct file pointers, in
            * reverse order so that if pointers are bigger than ints, the
            * int won't get until we're done.
            */
           fdp = ((int *)(cm + 1)) + nfds - 1;
           rp = ((struct file **)ALIGN(cm + 1)) + nfds - 1;
           for (i = 0; i < nfds; i++) {
                   fp = fdescp->fd_ofiles[*fdp];
                   *rp-- = fp;
                 fp->f_count++;                  fp->f_count++;
                 fp->f_msgcount++;                  fp->f_msgcount++;
                 unp_rights++;                  unp_rights++;

Legend:
Removed from v.1.23  
changed lines
  Added in v.1.24

CVSweb <webmaster@jp.NetBSD.org>