Mercurial > illumos > illumos-gate
annotate usr/src/lib/libc/port/stdio/_endopen.c @ 14015:e5fc7d0d7c24
3687 fopen() O_CLOEXEC support via the "e" flag
Reviewed by Robert Mustacchi <rm@joyent.com>
Reviewed by Richard Lowe <richlowe@richlowe.net>
Approved by Dan McDonald <danmcd@nexenta.com>
author | Theo Schlossnagle <jesus@omniti.com> |
---|---|
date | Wed, 17 Apr 2013 10:28:26 -0400 |
parents | febeba71273d |
children |
rev | line source |
---|---|
0 | 1 /* |
2 * CDDL HEADER START | |
3 * | |
4 * The contents of this file are subject to the terms of the | |
1846
376b8b33ed65
PSARC 2006/162 Extended FILE space for 32-bit Solaris processes
craigm
parents:
0
diff
changeset
|
5 * Common Development and Distribution License (the "License"). |
376b8b33ed65
PSARC 2006/162 Extended FILE space for 32-bit Solaris processes
craigm
parents:
0
diff
changeset
|
6 * You may not use this file except in compliance with the License. |
0 | 7 * |
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE | |
9 * or http://www.opensolaris.org/os/licensing. | |
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 */ | |
6812 | 21 |
0 | 22 /* |
6812 | 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. |
0 | 24 * Use is subject to license terms. |
25 */ | |
26 | |
27 /* Copyright (c) 1988 AT&T */ | |
28 /* All Rights Reserved */ | |
29 | |
14015
e5fc7d0d7c24
3687 fopen() O_CLOEXEC support via the "e" flag
Theo Schlossnagle <jesus@omniti.com>
parents:
6812
diff
changeset
|
30 /* Copyright (c) 2013 OmniTI Computer Consulting, Inc. All rights reserved. */ |
0 | 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 { | |
14015
e5fc7d0d7c24
3687 fopen() O_CLOEXEC support via the "e" flag
Theo Schlossnagle <jesus@omniti.com>
parents:
6812
diff
changeset
|
58 int oflag, fd, fflag, eflag, plusflag; |
e5fc7d0d7c24
3687 fopen() O_CLOEXEC support via the "e" flag
Theo Schlossnagle <jesus@omniti.com>
parents:
6812
diff
changeset
|
59 const char *echr; |
0 | 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; | |
1846
376b8b33ed65
PSARC 2006/162 Extended FILE space for 32-bit Solaris processes
craigm
parents:
0
diff
changeset
|
69 fflag = _IOREAD; |
0 | 70 break; |
71 case 'w': | |
72 oflag = O_WRONLY | O_TRUNC | O_CREAT; | |
1846
376b8b33ed65
PSARC 2006/162 Extended FILE space for 32-bit Solaris processes
craigm
parents:
0
diff
changeset
|
73 fflag = _IOWRT; |
0 | 74 break; |
75 case 'a': | |
76 oflag = O_WRONLY | O_APPEND | O_CREAT; | |
1846
376b8b33ed65
PSARC 2006/162 Extended FILE space for 32-bit Solaris processes
craigm
parents:
0
diff
changeset
|
77 fflag = _IOWRT; |
0 | 78 break; |
79 } | |
14015
e5fc7d0d7c24
3687 fopen() O_CLOEXEC support via the "e" flag
Theo Schlossnagle <jesus@omniti.com>
parents:
6812
diff
changeset
|
80 |
e5fc7d0d7c24
3687 fopen() O_CLOEXEC support via the "e" flag
Theo Schlossnagle <jesus@omniti.com>
parents:
6812
diff
changeset
|
81 plusflag = 0; |
e5fc7d0d7c24
3687 fopen() O_CLOEXEC support via the "e" flag
Theo Schlossnagle <jesus@omniti.com>
parents:
6812
diff
changeset
|
82 eflag = 0; |
e5fc7d0d7c24
3687 fopen() O_CLOEXEC support via the "e" flag
Theo Schlossnagle <jesus@omniti.com>
parents:
6812
diff
changeset
|
83 for (echr = type + 1; *echr != '\0'; echr++) { |
e5fc7d0d7c24
3687 fopen() O_CLOEXEC support via the "e" flag
Theo Schlossnagle <jesus@omniti.com>
parents:
6812
diff
changeset
|
84 switch (*echr) { |
e5fc7d0d7c24
3687 fopen() O_CLOEXEC support via the "e" flag
Theo Schlossnagle <jesus@omniti.com>
parents:
6812
diff
changeset
|
85 /* UNIX ignores 'b' and treats text and binary the same */ |
e5fc7d0d7c24
3687 fopen() O_CLOEXEC support via the "e" flag
Theo Schlossnagle <jesus@omniti.com>
parents:
6812
diff
changeset
|
86 default: |
e5fc7d0d7c24
3687 fopen() O_CLOEXEC support via the "e" flag
Theo Schlossnagle <jesus@omniti.com>
parents:
6812
diff
changeset
|
87 break; |
e5fc7d0d7c24
3687 fopen() O_CLOEXEC support via the "e" flag
Theo Schlossnagle <jesus@omniti.com>
parents:
6812
diff
changeset
|
88 case '+': |
e5fc7d0d7c24
3687 fopen() O_CLOEXEC support via the "e" flag
Theo Schlossnagle <jesus@omniti.com>
parents:
6812
diff
changeset
|
89 plusflag = 1; |
e5fc7d0d7c24
3687 fopen() O_CLOEXEC support via the "e" flag
Theo Schlossnagle <jesus@omniti.com>
parents:
6812
diff
changeset
|
90 break; |
e5fc7d0d7c24
3687 fopen() O_CLOEXEC support via the "e" flag
Theo Schlossnagle <jesus@omniti.com>
parents:
6812
diff
changeset
|
91 case 'e': |
e5fc7d0d7c24
3687 fopen() O_CLOEXEC support via the "e" flag
Theo Schlossnagle <jesus@omniti.com>
parents:
6812
diff
changeset
|
92 eflag = 1; |
e5fc7d0d7c24
3687 fopen() O_CLOEXEC support via the "e" flag
Theo Schlossnagle <jesus@omniti.com>
parents:
6812
diff
changeset
|
93 break; |
e5fc7d0d7c24
3687 fopen() O_CLOEXEC support via the "e" flag
Theo Schlossnagle <jesus@omniti.com>
parents:
6812
diff
changeset
|
94 } |
e5fc7d0d7c24
3687 fopen() O_CLOEXEC support via the "e" flag
Theo Schlossnagle <jesus@omniti.com>
parents:
6812
diff
changeset
|
95 } |
e5fc7d0d7c24
3687 fopen() O_CLOEXEC support via the "e" flag
Theo Schlossnagle <jesus@omniti.com>
parents:
6812
diff
changeset
|
96 if (eflag) { |
e5fc7d0d7c24
3687 fopen() O_CLOEXEC support via the "e" flag
Theo Schlossnagle <jesus@omniti.com>
parents:
6812
diff
changeset
|
97 /* Subsequent to a mode flag, 'e' indicates O_CLOEXEC */ |
e5fc7d0d7c24
3687 fopen() O_CLOEXEC support via the "e" flag
Theo Schlossnagle <jesus@omniti.com>
parents:
6812
diff
changeset
|
98 oflag = oflag | O_CLOEXEC; |
e5fc7d0d7c24
3687 fopen() O_CLOEXEC support via the "e" flag
Theo Schlossnagle <jesus@omniti.com>
parents:
6812
diff
changeset
|
99 } |
e5fc7d0d7c24
3687 fopen() O_CLOEXEC support via the "e" flag
Theo Schlossnagle <jesus@omniti.com>
parents:
6812
diff
changeset
|
100 if (plusflag) { |
0 | 101 oflag = (oflag & ~(O_RDONLY | O_WRONLY)) | O_RDWR; |
1846
376b8b33ed65
PSARC 2006/162 Extended FILE space for 32-bit Solaris processes
craigm
parents:
0
diff
changeset
|
102 fflag = _IORW; |
376b8b33ed65
PSARC 2006/162 Extended FILE space for 32-bit Solaris processes
craigm
parents:
0
diff
changeset
|
103 } |
0 | 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 | |
1846
376b8b33ed65
PSARC 2006/162 Extended FILE space for 32-bit Solaris processes
craigm
parents:
0
diff
changeset
|
114 /* As long as we make sure _flag stays != 0, we don't need to lock */ |
0 | 115 #ifdef _LP64 |
116 iop->_file = fd; | |
1846
376b8b33ed65
PSARC 2006/162 Extended FILE space for 32-bit Solaris processes
craigm
parents:
0
diff
changeset
|
117 iop->_flag = (iop->_flag & ~0377) | fflag; |
0 | 118 #else |
1846
376b8b33ed65
PSARC 2006/162 Extended FILE space for 32-bit Solaris processes
craigm
parents:
0
diff
changeset
|
119 if (fd <= _FILE_FD_MAX) { |
376b8b33ed65
PSARC 2006/162 Extended FILE space for 32-bit Solaris processes
craigm
parents:
0
diff
changeset
|
120 SET_FILE(iop, fd); |
376b8b33ed65
PSARC 2006/162 Extended FILE space for 32-bit Solaris processes
craigm
parents:
0
diff
changeset
|
121 } else if (_file_set(iop, fd, type) != 0) { |
376b8b33ed65
PSARC 2006/162 Extended FILE space for 32-bit Solaris processes
craigm
parents:
0
diff
changeset
|
122 /* errno set in _file_set() */ |
0 | 123 (void) close(fd); |
124 return (NULL); | |
125 } | |
1846
376b8b33ed65
PSARC 2006/162 Extended FILE space for 32-bit Solaris processes
craigm
parents:
0
diff
changeset
|
126 iop->_flag = fflag; |
0 | 127 #endif /* _LP64 */ |
128 | |
129 if (oflag == (O_WRONLY | O_APPEND | O_CREAT)) { /* type == "a" */ | |
130 if (lseek64(fd, (off64_t)0, SEEK_END) < (off64_t)0) { | |
131 (void) close(fd); | |
132 return (NULL); | |
133 } | |
134 } | |
135 | |
136 return (iop); | |
137 } |