Branch data Line data Source code
1 : : /*- 2 : : * SPDX-License-Identifier: BSD-3-Clause 3 : : * 4 : : * Copyright (c) 1990, 1993 5 : : * The Regents of the University of California. All rights reserved. 6 : : * 7 : : * This code is derived from software contributed to Berkeley by 8 : : * Chris Torek. 9 : : * 10 : : * Redistribution and use in source and binary forms, with or without 11 : : * modification, are permitted provided that the following conditions 12 : : * are met: 13 : : * 1. Redistributions of source code must retain the above copyright 14 : : * notice, this list of conditions and the following disclaimer. 15 : : * 2. Redistributions in binary form must reproduce the above copyright 16 : : * notice, this list of conditions and the following disclaimer in the 17 : : * documentation and/or other materials provided with the distribution. 18 : : * 3. Neither the name of the University nor the names of its contributors 19 : : * may be used to endorse or promote products derived from this software 20 : : * without specific prior written permission. 21 : : * 22 : : * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 : : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 : : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 : : * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 : : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 : : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 : : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 : : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 : : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 : : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 : : * SUCH DAMAGE. 33 : : */ 34 : : 35 : : #if defined(LIBC_SCCS) && !defined(lint) 36 : : static char sccsid[] = "@(#)flags.c 8.1 (Berkeley) 6/4/93"; 37 : : #endif /* LIBC_SCCS and not lint */ 38 : : #include <sys/cdefs.h> 39 : : #include "bsd_compat.h" 40 : : __FBSDID("$FreeBSD: head/lib/libc/stdio/flags.c 326025 2017-11-20 19:49:47Z pfg $"); 41 : : 42 : : #include <sys/types.h> 43 : : #include <sys/file.h> 44 : : #include <stdio.h> 45 : : #include <errno.h> 46 : : #include <fcntl.h> 47 : : 48 : : /* 49 : : * Return the (stdio) flags for a given mode. Store the flags 50 : : * to be passed to an _open() syscall through *optr. 51 : : * Return 1 on error. 52 : : */ 53 : : int 54 : 19 : checkflags(const char *mode, int *optr) 55 : : { 56 : : int ret, m, o, known; 57 : 19 : ret = 0; 58 : : 59 [ - + + - ]: 19 : switch (*mode++) { 60 : : 61 : : case 'r': /* open for reading */ 62 : 5 : ret = 1; 63 : 5 : m = O_RDONLY; 64 : 5 : o = 0; 65 : 5 : break; 66 : : 67 : : case 'w': /* open for writing */ 68 : 14 : ret = 1; 69 : 14 : m = O_WRONLY; 70 : 14 : o = O_CREAT | O_TRUNC; 71 : 14 : break; 72 : : 73 : : case 'a': /* open for appending */ 74 : 0 : ret = 1; 75 : 0 : m = O_WRONLY; 76 : 0 : o = O_CREAT | O_APPEND; 77 : 0 : break; 78 : : 79 : : default: /* illegal mode */ 80 : 0 : errno = EINVAL; 81 : 0 : return (0); 82 : : } 83 : : 84 : 19 : do { 85 : 33 : known = 1; 86 [ + - + - : 33 : switch (*mode++) { - ] 87 : : case 'b': 88 : : /* 'b' (binary) is ignored */ 89 : 0 : break; 90 : : case '+': 91 : : /* [rwa][b]\+ means read and write */ 92 : 14 : ret = 1; 93 : 14 : m = O_RDWR; 94 : 14 : break; 95 : : case 'x': 96 : : /* 'x' means exclusive (fail if the file exists) */ 97 : 0 : o |= O_EXCL; 98 : 0 : break; 99 : : case 'e': 100 : : /* set close-on-exec */ 101 : 0 : o |= O_CLOEXEC; 102 : 0 : break; 103 : : default: 104 : 19 : known = 0; 105 : 19 : break; 106 : : } 107 [ + + ]: 33 : } while (known); 108 : : 109 [ - + # # ]: 19 : if ((o & O_EXCL) != 0 && m == O_RDONLY) { 110 : 0 : errno = EINVAL; 111 : 0 : return (1); 112 : : } 113 : : 114 : 19 : *optr = m | o; 115 : 19 : return (ret); 116 : 19 : }