Print this page
3687 fopen() O_CLOEXEC support via the "e" flag


  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 2008 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 /*      Copyright (c) 1988 AT&T     */
  28 /*        All Rights Reserved   */
  29 
  30 #pragma ident   "%Z%%M% %I%     %E% SMI"
  31 
  32 /*
  33  *      This routine is a special case, in that it is aware of
  34  *      both small and large file interfaces. It must be built
  35  *      in the small compilation environment.
  36  */
  37 
  38 #include "lint.h"
  39 #include "file64.h"
  40 #include <mtlib.h>
  41 #include <sys/types.h>
  42 #include <stdio.h>
  43 #include <fcntl.h>
  44 #include <unistd.h>
  45 #include <limits.h>
  46 #include <thread.h>
  47 #include <synch.h>
  48 #include "stdiom.h"
  49 #include <errno.h>
  50 
  51 /*
  52  * open UNIX file name, associate with iop
  53  */
  54 
  55 FILE *
  56 _endopen(const char *name, const char *type, FILE *iop, int largefile)
  57 {
  58         int oflag, fd, fflag;
  59         char plus;
  60 
  61         if (iop == NULL)
  62                 return (NULL);
  63         switch (type[0]) {
  64         default:
  65                 errno = EINVAL;
  66                 return (NULL);
  67         case 'r':
  68                 oflag = O_RDONLY;
  69                 fflag = _IOREAD;
  70                 break;
  71         case 'w':
  72                 oflag = O_WRONLY | O_TRUNC | O_CREAT;
  73                 fflag = _IOWRT;
  74                 break;
  75         case 'a':
  76                 oflag = O_WRONLY | O_APPEND | O_CREAT;
  77                 fflag = _IOWRT;
  78                 break;
  79         }





  80         /* UNIX ignores 'b' and treats text and binary the same */
  81         if ((plus = type[1]) == 'b')
  82                 plus = type[2];
  83         if (plus == '+') {












  84                 oflag = (oflag & ~(O_RDONLY | O_WRONLY)) | O_RDWR;
  85                 fflag = _IORW;
  86         }
  87 
  88         /* select small or large file open based on flag */
  89         if (largefile) {
  90                 fd = open64(name, oflag, 0666);
  91         } else {
  92                 fd = open(name, oflag, 0666);
  93         }
  94         if (fd < 0)
  95                 return (NULL);
  96 
  97         /* As long as we make sure _flag stays != 0, we don't need to lock */
  98 #ifdef  _LP64
  99         iop->_file = fd;
 100         iop->_flag = (iop->_flag & ~0377) | fflag;
 101 #else
 102         if (fd <= _FILE_FD_MAX) {
 103                 SET_FILE(iop, fd);


  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 2008 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 /*      Copyright (c) 1988 AT&T     */
  28 /*        All Rights Reserved   */
  29 
  30 /* Copyright (c) 2013 OmniTI Computer Consulting, Inc. All rights reserved. */
  31 
  32 /*
  33  *      This routine is a special case, in that it is aware of
  34  *      both small and large file interfaces. It must be built
  35  *      in the small compilation environment.
  36  */
  37 
  38 #include "lint.h"
  39 #include "file64.h"
  40 #include <mtlib.h>
  41 #include <sys/types.h>
  42 #include <stdio.h>
  43 #include <fcntl.h>
  44 #include <unistd.h>
  45 #include <limits.h>
  46 #include <thread.h>
  47 #include <synch.h>
  48 #include "stdiom.h"
  49 #include <errno.h>
  50 
  51 /*
  52  * open UNIX file name, associate with iop
  53  */
  54 
  55 FILE *
  56 _endopen(const char *name, const char *type, FILE *iop, int largefile)
  57 {
  58         int oflag, fd, fflag, eflag, plusflag;
  59         const char *echr;
  60 
  61         if (iop == NULL)
  62                 return (NULL);
  63         switch (type[0]) {
  64         default:
  65                 errno = EINVAL;
  66                 return (NULL);
  67         case 'r':
  68                 oflag = O_RDONLY;
  69                 fflag = _IOREAD;
  70                 break;
  71         case 'w':
  72                 oflag = O_WRONLY | O_TRUNC | O_CREAT;
  73                 fflag = _IOWRT;
  74                 break;
  75         case 'a':
  76                 oflag = O_WRONLY | O_APPEND | O_CREAT;
  77                 fflag = _IOWRT;
  78                 break;
  79         }
  80 
  81         plusflag = 0;
  82         eflag = 0;
  83         for (echr = type + 1; *echr != '\0'; echr++) {
  84                 switch (*echr) {
  85                 /* UNIX ignores 'b' and treats text and binary the same */
  86                 default:
  87                         break;
  88                 case '+':
  89                         plusflag = 1;
  90                         break;
  91                 case 'e':
  92                         eflag = 1;
  93                         break;
  94                 }
  95         }
  96         if (eflag) {
  97                 /* Subsequent to a mode flag, 'e' indicates O_CLOEXEC */
  98                 oflag = oflag | O_CLOEXEC;
  99         }
 100         if (plusflag) {
 101                 oflag = (oflag & ~(O_RDONLY | O_WRONLY)) | O_RDWR;
 102                 fflag = _IORW;
 103         }
 104 
 105         /* select small or large file open based on flag */
 106         if (largefile) {
 107                 fd = open64(name, oflag, 0666);
 108         } else {
 109                 fd = open(name, oflag, 0666);
 110         }
 111         if (fd < 0)
 112                 return (NULL);
 113 
 114         /* As long as we make sure _flag stays != 0, we don't need to lock */
 115 #ifdef  _LP64
 116         iop->_file = fd;
 117         iop->_flag = (iop->_flag & ~0377) | fflag;
 118 #else
 119         if (fd <= _FILE_FD_MAX) {
 120                 SET_FILE(iop, fd);