Print this page
3665 Implement O_CLOEXEC as an open() flag
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Gordon Ross <gwr@nexenta.com>
Reviewed by: Dan McDonald <danmcd@nexenta.com>


  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
  24  */
  25 
  26 /*      Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
  27 /*        All Rights Reserved   */
  28 
  29 /*



  30  * Portions of this source code were derived from Berkeley 4.3 BSD
  31  * under license from the Regents of the University of California.
  32  */
  33 
  34 #include <sys/param.h>
  35 #include <sys/isa_defs.h>
  36 #include <sys/types.h>
  37 #include <sys/sysmacros.h>
  38 #include <sys/user.h>
  39 #include <sys/systm.h>
  40 #include <sys/errno.h>
  41 #include <sys/fcntl.h>
  42 #include <sys/stat.h>
  43 #include <sys/vnode.h>
  44 #include <sys/vfs.h>
  45 #include <sys/file.h>
  46 #include <sys/mode.h>
  47 #include <sys/uio.h>
  48 #include <sys/debug.h>
  49 #include <c2/audit.h>


 209                         /*
 210                          * Last arg is a don't-care term if
 211                          * !(filemode & FCREAT).
 212                          */
 213                         error = vn_openat(open_filename, seg, filemode,
 214                             (int)(createmode & MODEMASK),
 215                             &vp, CRCREAT, PTOU(curproc)->u_cmask,
 216                             startvp, fd);
 217 
 218                         if (startvp != NULL)
 219                                 VN_RELE(startvp);
 220                         if (error == 0) {
 221                                 if ((vp->v_flag & VDUP) == 0) {
 222                                         fp->f_vnode = vp;
 223                                         mutex_exit(&fp->f_tlock);
 224                                         /*
 225                                          * We must now fill in the slot
 226                                          * falloc reserved.
 227                                          */
 228                                         setf(fd, fp);



 229                                         return (fd);
 230                                 } else {
 231                                         /*
 232                                          * Special handling for /dev/fd.
 233                                          * Give up the file pointer
 234                                          * and dup the indicated file descriptor
 235                                          * (in v_rdev). This is ugly, but I've
 236                                          * seen worse.
 237                                          */
 238                                         unfalloc(fp);
 239                                         dupfd = getminor(vp->v_rdev);
 240                                         type = vp->v_type;
 241                                         mutex_enter(&vp->v_lock);
 242                                         vp->v_flag &= ~VDUP;
 243                                         mutex_exit(&vp->v_lock);
 244                                         VN_RELE(vp);
 245                                         if (type != VCHR)
 246                                                 return (set_errno(EINVAL));
 247                                         if ((fp = getf(dupfd)) == NULL) {
 248                                                 setf(fd, NULL);
 249                                                 return (set_errno(EBADF));
 250                                         }
 251                                         mutex_enter(&fp->f_tlock);
 252                                         fp->f_count++;
 253                                         mutex_exit(&fp->f_tlock);
 254                                         setf(fd, fp);



 255                                         releasef(dupfd);
 256                                 }
 257                                 return (fd);
 258                         } else {
 259                                 setf(fd, NULL);
 260                                 unfalloc(fp);
 261                                 return (set_errno(error));
 262                         }
 263                 }
 264         } else {
 265                 error = EINVAL;
 266         }
 267 out:
 268         if (startvp != NULL)
 269                 VN_RELE(startvp);
 270         return (set_errno(error));
 271 }
 272 
 273 #define OPENMODE32(fmode)       (((fmode) & (FSEARCH | FEXEC))? \
 274                                     (fmode) : (fmode) - FOPEN)




  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
  24  */
  25 
  26 /*      Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
  27 /*        All Rights Reserved   */
  28 
  29 /*
  30  * Copyright (c) 2013, OmniTI Computer Consulting, Inc. All rights reserved.
  31  */
  32 /*
  33  * Portions of this source code were derived from Berkeley 4.3 BSD
  34  * under license from the Regents of the University of California.
  35  */
  36 
  37 #include <sys/param.h>
  38 #include <sys/isa_defs.h>
  39 #include <sys/types.h>
  40 #include <sys/sysmacros.h>
  41 #include <sys/user.h>
  42 #include <sys/systm.h>
  43 #include <sys/errno.h>
  44 #include <sys/fcntl.h>
  45 #include <sys/stat.h>
  46 #include <sys/vnode.h>
  47 #include <sys/vfs.h>
  48 #include <sys/file.h>
  49 #include <sys/mode.h>
  50 #include <sys/uio.h>
  51 #include <sys/debug.h>
  52 #include <c2/audit.h>


 212                         /*
 213                          * Last arg is a don't-care term if
 214                          * !(filemode & FCREAT).
 215                          */
 216                         error = vn_openat(open_filename, seg, filemode,
 217                             (int)(createmode & MODEMASK),
 218                             &vp, CRCREAT, PTOU(curproc)->u_cmask,
 219                             startvp, fd);
 220 
 221                         if (startvp != NULL)
 222                                 VN_RELE(startvp);
 223                         if (error == 0) {
 224                                 if ((vp->v_flag & VDUP) == 0) {
 225                                         fp->f_vnode = vp;
 226                                         mutex_exit(&fp->f_tlock);
 227                                         /*
 228                                          * We must now fill in the slot
 229                                          * falloc reserved.
 230                                          */
 231                                         setf(fd, fp);
 232                                         if ((filemode & FCLOEXEC) != 0) {
 233                                                 f_setfd(fd, FD_CLOEXEC);
 234                                         }
 235                                         return (fd);
 236                                 } else {
 237                                         /*
 238                                          * Special handling for /dev/fd.
 239                                          * Give up the file pointer
 240                                          * and dup the indicated file descriptor
 241                                          * (in v_rdev). This is ugly, but I've
 242                                          * seen worse.
 243                                          */
 244                                         unfalloc(fp);
 245                                         dupfd = getminor(vp->v_rdev);
 246                                         type = vp->v_type;
 247                                         mutex_enter(&vp->v_lock);
 248                                         vp->v_flag &= ~VDUP;
 249                                         mutex_exit(&vp->v_lock);
 250                                         VN_RELE(vp);
 251                                         if (type != VCHR)
 252                                                 return (set_errno(EINVAL));
 253                                         if ((fp = getf(dupfd)) == NULL) {
 254                                                 setf(fd, NULL);
 255                                                 return (set_errno(EBADF));
 256                                         }
 257                                         mutex_enter(&fp->f_tlock);
 258                                         fp->f_count++;
 259                                         mutex_exit(&fp->f_tlock);
 260                                         setf(fd, fp);
 261                                         if ((filemode & FCLOEXEC) != 0) {
 262                                                 f_setfd(fd, FD_CLOEXEC);
 263                                         }
 264                                         releasef(dupfd);
 265                                 }
 266                                 return (fd);
 267                         } else {
 268                                 setf(fd, NULL);
 269                                 unfalloc(fp);
 270                                 return (set_errno(error));
 271                         }
 272                 }
 273         } else {
 274                 error = EINVAL;
 275         }
 276 out:
 277         if (startvp != NULL)
 278                 VN_RELE(startvp);
 279         return (set_errno(error));
 280 }
 281 
 282 #define OPENMODE32(fmode)       (((fmode) & (FSEARCH | FEXEC))? \
 283                                     (fmode) : (fmode) - FOPEN)