1 /*********************************************************************** 2 * * 3 * This software is part of the ast package * 4 * Copyright (c) 1985-2009 AT&T Intellectual Property * 5 * and is licensed under the * 6 * Common Public License, Version 1.0 * 7 * by AT&T Intellectual Property * 8 * * 9 * A copy of the License is available at * 10 * http://www.opensource.org/licenses/cpl1.0.txt * 11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 12 * * 13 * Information and Software Systems Research * 14 * AT&T Research * 15 * Florham Park NJ * 16 * * 17 * Glenn Fowler <gsf@research.att.com> * 18 * David Korn <dgk@research.att.com> * 19 * Phong Vo <kpv@research.att.com> * 20 * * 21 ***********************************************************************/ 22 #pragma prototyped 23 24 /* 25 * -last 3 arg open 26 */ 27 28 #include <ast.h> 29 30 #if !defined(open) || !defined(_ast_O_LOCAL) 31 32 NoN(open) 33 34 #else 35 36 #undef open 37 38 extern int open(const char*, int, ...); 39 40 #include <ls.h> 41 #include <error.h> 42 43 #ifdef O_NOCTTY 44 #include <ast_tty.h> 45 #endif 46 47 int 48 _ast_open(const char* path, int op, ...) 49 { 50 int fd; 51 int mode; 52 int save_errno; 53 struct stat st; 54 va_list ap; 55 56 save_errno = errno; 57 va_start(ap, op); 58 mode = (op & O_CREAT) ? va_arg(ap, int) : S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH; 59 va_end(ap); 60 if (op & ~(_ast_O_LOCAL-1)) 61 { 62 if (!(op & O_CREAT)) 63 op &= ~O_EXCL; 64 for (;;) 65 { 66 if (op & O_TRUNC) 67 { 68 if ((op & O_EXCL) && !access(path, F_OK)) 69 { 70 errno = EEXIST; 71 return(-1); 72 } 73 if ((fd = creat(path, (op & O_EXCL) ? 0 : mode)) < 0) 74 return(-1); 75 if (op & O_EXCL) 76 { 77 if (fstat(fd, &st) || (st.st_mode & S_IPERM)) 78 { 79 errno = EEXIST; 80 close(fd); 81 return(-1); 82 } 83 #if _lib_fchmod 84 if (mode && fchmod(fd, mode)) 85 #else 86 if (mode && chmod(path, mode)) 87 #endif 88 errno = save_errno; 89 } 90 if ((op & O_ACCMODE) == O_RDWR) 91 { 92 close(fd); 93 op &= ~(O_CREAT|O_TRUNC); 94 continue; 95 } 96 } 97 else if ((fd = open(path, op & (_ast_O_LOCAL-1), mode)) < 0) 98 { 99 if (op & O_CREAT) 100 { 101 op |= O_TRUNC; 102 continue; 103 } 104 return(-1); 105 } 106 else if ((op & O_APPEND) && lseek(fd, 0L, SEEK_END) == -1L) 107 errno = save_errno; 108 #if O_NOCTTY 109 if ((op & O_NOCTTY) && ioctl(fd, TIOCNOTTY, 0)) 110 errno = save_errno; 111 #endif 112 break; 113 } 114 } 115 else fd = open(path, op, mode); 116 return(fd); 117 } 118 119 #endif 120