Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/cygwin/fhandler_raw.cc')
-rw-r--r--winsup/cygwin/fhandler_raw.cc86
1 files changed, 48 insertions, 38 deletions
diff --git a/winsup/cygwin/fhandler_raw.cc b/winsup/cygwin/fhandler_raw.cc
index 20f2de513..2b8470a36 100644
--- a/winsup/cygwin/fhandler_raw.cc
+++ b/winsup/cygwin/fhandler_raw.cc
@@ -1,6 +1,6 @@
/* fhandler_raw.cc. See fhandler.h for a description of the fhandler classes.
- Copyright 1999, 2000, 2001 Red Hat, Inc.
+ Copyright 1999, 2000, 2001, 2002 Red Hat, Inc.
This file is part of Cygwin.
@@ -10,12 +10,12 @@
#include "winsup.h"
#include <sys/termios.h>
-#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <cygwin/rdevio.h>
#include <sys/mtio.h>
+#include <ntdef.h>
#include "cygerrno.h"
#include "perprocess.h"
#include "security.h"
@@ -23,6 +23,7 @@
#include "path.h"
#include "dtable.h"
#include "cygheap.h"
+#include "ntdll.h"
/* static wrapper functions to hide the effect of media changes and
bus resets which occurs after a new media is inserted. This is
@@ -55,7 +56,7 @@ static BOOL read_file (HANDLE fh, void *buf, DWORD to_read,
BOOL ret;
*err = 0;
- if (!(ret = ReadFile(fh, buf, to_read, read, 0)))
+ if (!(ret = ReadFile (fh, buf, to_read, read, 0)))
{
if ((*err = GetLastError ()) == ERROR_MEDIA_CHANGED
|| *err == ERROR_BUS_RESET)
@@ -84,7 +85,6 @@ fhandler_dev_raw::clear (void)
eof_detected = 0;
lastblk_to_read = 0;
varblkop = 0;
- unit = 0;
}
int
@@ -116,10 +116,10 @@ fhandler_dev_raw::writebuf (void)
return ret;
}
-fhandler_dev_raw::fhandler_dev_raw (DWORD devtype, const char *name, int unit) : fhandler_base (devtype, name)
+fhandler_dev_raw::fhandler_dev_raw (DWORD devtype, int nunit)
+ : fhandler_base (devtype), unit (nunit)
{
clear ();
- this->unit = unit;
set_need_fork_fixup ();
}
@@ -131,25 +131,56 @@ fhandler_dev_raw::~fhandler_dev_raw (void)
}
int
-fhandler_dev_raw::open (const char *path, int flags, mode_t)
+fhandler_dev_raw::open (path_conv *real_path, int flags, mode_t)
{
- path_conv real_path (path, PC_SYM_IGNORE);
- int ret;
+ if (!wincap.has_raw_devices ())
+ {
+ set_errno (ENOENT);
+ debug_printf ("%s is accessible under NT/W2K only",real_path->get_win32());
+ return 0;
+ }
- set_name (path, real_path.get_win32 ());
+ /* Check for illegal flags. */
+ if (flags & (O_APPEND | O_EXCL))
+ {
+ set_errno (EINVAL);
+ return 0;
+ }
/* Always open a raw device existing and binary. */
flags &= ~(O_CREAT | O_TRUNC);
flags |= O_BINARY;
- ret = fhandler_base::open (path, flags);
- if (ret)
+
+ DWORD access = GENERIC_READ | SYNCHRONIZE;
+ if (get_device () == FH_TAPE
+ || (flags & (O_RDONLY | O_WRONLY | O_RDWR)) == O_WRONLY
+ || (flags & (O_RDONLY | O_WRONLY | O_RDWR)) == O_RDWR)
+ access |= GENERIC_WRITE;
+
+ extern void str2buf2uni (UNICODE_STRING &, WCHAR *, const char *);
+ UNICODE_STRING dev;
+ WCHAR devname[MAX_PATH + 1];
+ str2buf2uni (dev, devname, real_path->get_win32 ());
+ OBJECT_ATTRIBUTES attr;
+ InitializeObjectAttributes (&attr, &dev, OBJ_CASE_INSENSITIVE, NULL, NULL);
+
+ HANDLE h;
+ IO_STATUS_BLOCK io;
+ NTSTATUS status = NtOpenFile (&h, access, &attr, &io, wincap.shared (),
+ FILE_SYNCHRONOUS_IO_NONALERT);
+ if (!NT_SUCCESS (status))
{
- if (devbufsiz > 1L)
- devbuf = new char [devbufsiz];
+ __seterrno_from_win_error (RtlNtStatusToDosError (status));
+ return 0;
}
- else
- devbufsiz = 0;
- return ret;
+
+ set_io_handle (h);
+ set_flags ((flags & ~O_TEXT) | O_BINARY);
+
+ if (devbufsiz > 1L)
+ devbuf = new char [devbufsiz];
+
+ return 1;
}
int
@@ -159,27 +190,6 @@ fhandler_dev_raw::close (void)
}
int
-fhandler_dev_raw::fstat (struct stat *buf)
-{
- if (!buf)
- {
- set_errno (EINVAL);
- return -1;
- }
-
- memset (buf, 0, sizeof *buf);
- buf->st_mode = S_IFCHR |
- S_IRUSR | S_IWUSR |
- S_IRGRP | S_IWGRP |
- S_IROTH | S_IWOTH;
- buf->st_nlink = 1;
- buf->st_blksize = devbuf ? devbufsiz : 1;
- buf->st_dev = buf->st_rdev = get_device () << 8 | (unit & 0xff);
-
- return 0;
-}
-
-int
fhandler_dev_raw::raw_read (void *ptr, size_t ulen)
{
DWORD bytes_read = 0;