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 "bsd_compat.h" 39 : : __FBSDID("$FreeBSD: head/lib/libc/stdio/flags.c 326025 2017-11-20 19:49:47Z pfg $"); 40 : : 41 : : #include <sys/types.h> 42 : : #include <sys/file.h> 43 : : #include <stdio.h> 44 : : #include <errno.h> 45 : : #include <fcntl.h> 46 : : 47 : : /* 48 : : * Return the (stdio) flags for a given mode. Store the flags 49 : : * to be passed to an _open() syscall through *optr. 50 : : * Return 1 on error. 51 : : */ 52 : : int 53 : 2 : checkflags(const char *mode, int *optr) 54 : : { 55 : : int ret, m, o, known; 56 : 2 : ret = 0; 57 : : 58 [ + - + - ]: 2 : switch (*mode++) { 59 : : 60 : : case 'r': /* open for reading */ 61 : 1 : ret = 1; 62 : 1 : m = O_RDONLY; 63 : 1 : o = 0; 64 : 1 : break; 65 : : 66 : : case 'w': /* open for writing */ 67 : 1 : ret = 1; 68 : 1 : m = O_WRONLY; 69 : 1 : o = O_CREAT | O_TRUNC; 70 : 1 : break; 71 : : 72 : : case 'a': /* open for appending */ 73 : 0 : ret = 1; 74 : 0 : m = O_WRONLY; 75 : 0 : o = O_CREAT | O_APPEND; 76 : 0 : break; 77 : : 78 : : default: /* illegal mode */ 79 : 0 : errno = EINVAL; 80 : 0 : return (0); 81 : : } 82 : : 83 : 3 : do { 84 : 3 : known = 1; 85 [ + - + - : 3 : switch (*mode++) { - ] 86 : : case 'b': 87 : : /* 'b' (binary) is ignored */ 88 : 0 : break; 89 : : case '+': 90 : : /* [rwa][b]\+ means read and write */ 91 : 1 : ret = 1; 92 : 1 : m = O_RDWR; 93 : 1 : break; 94 : : case 'x': 95 : : /* 'x' means exclusive (fail if the file exists) */ 96 : 0 : o |= O_EXCL; 97 : 0 : break; 98 : : case 'e': 99 : : /* set close-on-exec */ 100 : 0 : o |= O_CLOEXEC; 101 : 0 : break; 102 : : default: 103 : 2 : known = 0; 104 : 2 : break; 105 : : } 106 [ + + ]: 3 : } while (known); 107 : : 108 [ - + # # ]: 2 : if ((o & O_EXCL) != 0 && m == O_RDONLY) { 109 : 0 : errno = EINVAL; 110 : 0 : return (1); 111 : : } 112 : : 113 : 2 : *optr = m | o; 114 : 2 : return (ret); 115 : 2 : }