diff options
author | Christopher Faylor <me@cgf.cx> | 2000-07-09 05:29:51 +0000 |
---|---|---|
committer | Christopher Faylor <me@cgf.cx> | 2000-07-09 05:29:51 +0000 |
commit | bd4ec49671b07f93883c7e0c9142125525731714 (patch) | |
tree | 49c4d2e87d54048f97bea742896acb5b348ffda1 /winsup/cygwin/fhandler.cc | |
parent | 85219b356e249702b845cf667462584945b1735b (diff) | |
download | newlib-bd4ec49671b07f93883c7e0c9142125525731714.zip newlib-bd4ec49671b07f93883c7e0c9142125525731714.tar.gz newlib-bd4ec49671b07f93883c7e0c9142125525731714.tar.bz2 |
* cygwin.din: Export _getmode and getmode to allow querying of binary state of
an fd.
* external.cc (cygwin_internal): Add handling of perfile_table setting.
* fhandler.cc (perfile_table): New global.
(fhandler_base::get_default_fmode): New method to return a file's default mode
based on its name.
(fhandler_base::open): Use get_default_mode method to determine a file's mode.
Record file mode in file flags.
* fhandler.h (fhandler_base): Declare get_default_fmode
* syscalls.cc (getmode): New function.
* sys/cygwin.h (__cygwin_perfile): New structure.
(cygwin_getinfo_types): Move outside of WINVER conditional.
(per_process): Move inside of WINVER conditional.
Diffstat (limited to 'winsup/cygwin/fhandler.cc')
-rw-r--r-- | winsup/cygwin/fhandler.cc | 39 |
1 files changed, 33 insertions, 6 deletions
diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index c68ac0d..579de96 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -18,6 +18,8 @@ static NO_COPY const int CHUNK_SIZE = 1024; /* Used for crlf conversions */ static char fhandler_disk_dummy_name[] = "some disk file"; +struct __cygwin_perfile *perfile_table = NULL; + DWORD binmode; int @@ -249,6 +251,27 @@ fhandler_base::raw_write (const void *ptr, size_t len) return bytes_written; } +#define ACCFLAGS(x) (x & (O_RDONLY | O_WRONLY | O_RDWR)) +int +fhandler_base::get_default_fmode (int flags) +{ + if (perfile_table) + { + size_t nlen = strlen (get_name ()); + unsigned accflags = ACCFLAGS (flags); + for (__cygwin_perfile *pf = perfile_table; pf->name; pf++) + { + size_t pflen = strlen (pf->name); + const char *stem = get_name () + nlen - pflen; + if (pflen > nlen || (stem != get_name () && !isdirsep (stem[-1]))) + continue; + else if (strcasematch (stem, pf->name) && ACCFLAGS (pf->flags) == accflags) + return pf->flags & ~(O_RDONLY | O_WRONLY | O_RDWR); + } + } + return __fmode; +} + /* Open system call handler function. Path is now already checked for symlinks */ int @@ -262,8 +285,6 @@ fhandler_base::open (int flags, mode_t mode) syscall_printf ("(%s, %p)", get_win32_name (), flags); - set_flags (flags); - if (get_win32_name () == NULL) { set_errno (ENOENT); @@ -352,17 +373,23 @@ fhandler_base::open (int flags, mode_t mode) rpos_ = 0; rsize_ = -1; int bin; - if (flags & (O_BINARY | O_TEXT)) - bin = flags & O_TEXT ? 0 : O_BINARY; - else if (__fmode & O_BINARY) + int fmode; + if ((bin = flags & (O_BINARY | O_TEXT))) + /* nothing to do */; + else if ((fmode = get_default_fmode (flags)) & O_BINARY) bin = O_BINARY; - else if (__fmode & O_TEXT) + else if (fmode & O_TEXT) bin = O_TEXT; else if (get_device () == FH_DISK) bin = get_w_binary () || get_r_binary (); else bin = binmode || get_w_binary () || get_r_binary (); + if (bin & O_TEXT) + bin = 0; + + set_flags (flags | (bin ? O_BINARY : O_TEXT)); + set_r_binary (bin); set_w_binary (bin); syscall_printf ("filemode set to %s", bin ? "binary" : "text"); |