77 lines
1.7 KiB
C
77 lines
1.7 KiB
C
/* _ o p e n 3 */
|
|
|
|
/* For those ancient systems without three argument opens, we fake it.
|
|
* The following code works for:
|
|
*
|
|
* r O_RDONLY
|
|
* w O_WRONLY | O_CREAT | O_TRUNC
|
|
* a O_WRONLY | O_CREAT | O_APPEND
|
|
* r+ O_RDWR
|
|
* w+ O_RDWR | O_CREAT | O_TRUNC
|
|
* a+ O_RDWR | O_CREAT | O_APPEND
|
|
* other modes may not work
|
|
*
|
|
* Code based on open3.c from Bruce Evan's stdio. It is necessary to
|
|
* set the umask to zero so that creat works implies that open works.
|
|
* The O_APPEND mode is ignored since two argument opens don't support
|
|
* it at all.
|
|
*/
|
|
|
|
#include "stdiolib.h"
|
|
|
|
/*LINTLIBRARY*/
|
|
/*VARARGS2*/
|
|
/*ARGSUSED*/
|
|
|
|
#ifndef OPEN3
|
|
|
|
#undef open
|
|
|
|
int __open3 F2V(CONST char *, path, int, mode,
|
|
|
|
{
|
|
VA_LIST, arg, /* argument vector */
|
|
register int fd; /* file descriptor */
|
|
register int fmode; /* file mode */
|
|
int mask; /* saved umask */
|
|
int perms; /* permissions */
|
|
|
|
VA_START(arg, mode);)
|
|
|
|
/* Take fast local copy of mode */
|
|
fmode = mode;
|
|
|
|
/* r, a, r+ and a+ modes */
|
|
if ((fmode & O_TRUNC) == 0) {
|
|
if ((fd = open(path, fmode & (O_WRONLY|O_RDONLY|O_RDWR))) >= 0 ||
|
|
(fmode & O_CREAT) == 0 ||
|
|
errno != ENOENT)
|
|
goto Done;
|
|
|
|
/* Fall through on a and a+ modes => couldn't open because ENOENT */
|
|
}
|
|
|
|
/* Extract file permissions */
|
|
perms = VA_ARG(arg, int);
|
|
|
|
/* w and a modes */
|
|
if ((fmode & (O_WRONLY|O_RDONLY|O_RDWR)) != O_RDWR)
|
|
fd = creat(path, perms);
|
|
|
|
/* w+ and a+ modes */
|
|
else {
|
|
mask = umask(0);
|
|
if ((fd = creat(path, perms)) >= 0) {
|
|
(void) close(fd);
|
|
fd = open(path, O_RDWR);
|
|
(void) chmod(path, ~mask & perms);
|
|
}
|
|
(void) umask(mask);
|
|
}
|
|
|
|
Done:
|
|
VA_END(arg);
|
|
return fd;
|
|
}
|
|
#endif
|