1/*********************************************************************** 2* * 3* This software is part of the ast package * 4* Copyright (c) 1985-2011 AT&T Intellectual Property * 5* and is licensed under the * 6* Eclipse Public License, Version 1.0 * 7* by AT&T Intellectual Property * 8* * 9* A copy of the License is available at * 10* http://www.eclipse.org/org/documents/epl-v10.html * 11* (with md5 checksum b35adb5213ca9657e911e9befb180842) * 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 32NoN(open) 33 34#else 35 36#undef open 37 38extern 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 47int 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