aboutsummaryrefslogtreecommitdiff
path: root/winsup/cygwin/fhandler.cc
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2000-07-09 05:29:51 +0000
committerChristopher Faylor <me@cgf.cx>2000-07-09 05:29:51 +0000
commitbd4ec49671b07f93883c7e0c9142125525731714 (patch)
tree49c4d2e87d54048f97bea742896acb5b348ffda1 /winsup/cygwin/fhandler.cc
parent85219b356e249702b845cf667462584945b1735b (diff)
downloadnewlib-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.cc39
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");