123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- /* Defines for Sys V style 3-argument open call.
- Copyright (C) 1988, 1994, 1995, 1996 Free Software Foundation, Inc.
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the
- Free Software Foundation; either version 2, or (at your option) any later
- version.
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
- Public License for more details.
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 59 Place - Suite 330, Boston, MA 02111-1307, USA. */
- #include "system.h"
- #if EMUL_OPEN3
- /* open3.h -- #defines for the various flags for the Sys V style 3-argument
- open() call. On BSD or System 5, the system already has this in an
- include file. This file is needed for V7 and MINIX systems for the
- benefit of open3() in port.c, a routine that emulates the 3-argument call
- using system calls available on V7/MINIX.
- Written 1987-06-10 by Richard Todd.
- The names have been changed by John Gilmore, 1987-07-31, since Richard
- called it "bsdopen", and really this change was introduced in AT&T Unix
- systems before BSD picked it up. */
- /*-----------------------------------------------------------------------.
- | open3 -- routine to emulate the 3-argument open system. |
- | |
- | open3 (path, flag, mode); |
- | |
- | Attempts to open the file specified by the given pathname. The |
- | following flag bits specify options to the routine. Needless to say, |
- | you should only specify one of the first three. Function returns file |
- | descriptor if successful, -1 and errno if not. |
- `-----------------------------------------------------------------------*/
- /* The routine obeys the following mode arguments:
- O_RDONLY file open for read only
- O_WRONLY file open for write only
- O_RDWR file open for both read & write
- O_CREAT file is created with specified mode if it needs to be
- O_TRUNC if file exists, it is truncated to 0 bytes
- O_EXCL used with O_CREAT--routine returns error if file exists */
- /* Call that if present in most modern Unix systems. This version attempts
- to support all the flag bits except for O_NDELAY and O_APPEND, which are
- silently ignored. The emulation is not as efficient as the real thing
- (at worst, 4 system calls instead of one), but there's not much I can do
- about that. */
- /* Array to give arguments to access for various modes FIXME, this table
- depends on the specific integer values of O_*, and also contains
- integers (args to 'access') that should be #define's. */
- static int modes[] =
- {
- 04, /* O_RDONLY */
- 02, /* O_WRONLY */
- 06, /* O_RDWR */
- 06, /* invalid, just cope: O_WRONLY+O_RDWR */
- };
- /* Shut off the automatic emulation of open(), we'll need it. */
- #undef open
- int
- open3 (char *path, int flags, int mode)
- {
- int exists = 1;
- int call_creat = 0;
- /* We actually do the work by calling the open() or creat() system
- call, depending on the flags. Call_creat is true if we will use
- creat(), false if we will use open(). */
- /* See if the file exists and is accessible in the requested mode.
- Strictly speaking we shouldn't be using access, since access checks
- against real uid, and the open call should check against euid. Most
- cases real uid == euid, so it won't matter. FIXME. FIXME, the
- construction "flags & 3" and the modes table depends on the specific
- integer values of the O_* #define's. Foo! */
- if (access (path, modes[flags & 3]) < 0)
- {
- if (errno == ENOENT)
- {
- /* The file does not exist. */
- exists = 0;
- }
- else
- {
- /* Probably permission violation. */
- if (flags & O_EXCL)
- {
- /* Oops, the file exists, we didn't want it. No matter
- what the error, claim EEXIST. */
- errno = EEXIST; /* FIXME: errno should be read-only */
- }
- return -1;
- }
- }
- /* If we have the O_CREAT bit set, check for O_EXCL. */
- if (flags & O_CREAT)
- {
- if ((flags & O_EXCL) && exists)
- {
- /* Oops, the file exists and we didn't want it to. */
- errno = EEXIST; /* FIXME: errno should be read-only */
- return -1;
- }
- /* If the file doesn't exist, be sure to call creat() so that it
- will be created with the proper mode. */
- if (!exists)
- call_creat = 1;
- }
- else
- {
- /* If O_CREAT isn't set and the file doesn't exist, error. */
- if (!exists)
- {
- errno = ENOENT; /* FIXME: errno should be read-only */
- return -1;
- }
- }
- /* If the O_TRUNC flag is set and the file exists, we want to call
- creat() anyway, since creat() guarantees that the file will be
- truncated and open()-for-writing doesn't. (If the file doesn't
- exist, we're calling creat() anyway and the file will be created
- with zero length.) */
- if ((flags & O_TRUNC) && exists)
- call_creat = 1;
- /* Actually do the call. */
- if (call_creat)
- /* Call creat. May have to close and reopen the file if we want
- O_RDONLY or O_RDWR access -- creat() only gives O_WRONLY. */
- {
- int fd = creat (path, mode);
- if (fd < 0 || (flags & O_WRONLY))
- return fd;
- if (close (fd) < 0)
- return -1;
- /* Fall out to reopen the file we've created. */
- }
- /* Calling old open, we strip most of the new flags just in case. */
- return open (path, flags & (O_RDONLY | O_WRONLY | O_RDWR | O_BINARY));
- }
- #endif /* EMUL_OPEN3 */
|