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:
authorCorinna Vinschen <corinna@vinschen.de>2000-10-07 21:35:36 +0400
committerCorinna Vinschen <corinna@vinschen.de>2000-10-07 21:35:36 +0400
commit4ea34a68506bcd5233be1a3bfca9b81b5f9234b2 (patch)
tree7c8d1066f9b48e736b8be2c52d81708cfbe59e35
parent7aadaf0f7eefe50e4f7d4aa71b71b1f85e37ea6e (diff)
* fhandler.h (fhandler_dev_mem): Add methods mmap, munmap and msync.
Add `unit' member. * fhandler_mem.cc (fhandler_dev_mem): Initialize `unit' as well. (init): Care for differences between /dev/mem, /dev/kmem (not implemented yet) and /dev/port. (open): Change debug message to reflect the device. (mmap): New function. (munmap): Ditto. (msync): Ditto. (fstat): Use unit when setting st_dev in stat structure. * mmap.cc (mmap): Handle MAP_ANONYMOUS flag. Change error handling slightly. * path.cc (get_device_number): Handle /dev/port.
-rw-r--r--winsup/cygwin/ChangeLog16
-rw-r--r--winsup/cygwin/fhandler.h16
-rw-r--r--winsup/cygwin/fhandler_mem.cc159
-rw-r--r--winsup/cygwin/mmap.cc14
-rw-r--r--winsup/cygwin/path.cc10
5 files changed, 185 insertions, 30 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index ef5486235..f00bf5bd3 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,19 @@
+Sat Oct 7 19:25:00 2000 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler.h (fhandler_dev_mem): Add methods mmap, munmap and msync.
+ Add `unit' member.
+ * fhandler_mem.cc (fhandler_dev_mem): Initialize `unit' as well.
+ (init): Care for differences between /dev/mem, /dev/kmem (not
+ implemented yet) and /dev/port.
+ (open): Change debug message to reflect the device.
+ (mmap): New function.
+ (munmap): Ditto.
+ (msync): Ditto.
+ (fstat): Use unit when setting st_dev in stat structure.
+ * mmap.cc (mmap): Handle MAP_ANONYMOUS flag.
+ Change error handling slightly.
+ * path.cc (get_device_number): Handle /dev/port.
+
Fri Oct 6 23:21:29 2000 Christopher Faylor <cgf@cygnus.com>
* syscalls.cc (_read): Behave properly when passed previous version of
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 16b0e7332..3f8a1c1e0 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -467,10 +467,9 @@ public:
BOOL is_device () { return FALSE; }
int fstat (struct stat *buf);
- virtual HANDLE mmap (caddr_t *addr, size_t len, DWORD access,
- int flags, off_t off);
- virtual int munmap (HANDLE h, caddr_t addr, size_t len);
- virtual int msync (HANDLE h, caddr_t addr, size_t len, int flags);
+ HANDLE mmap (caddr_t *addr, size_t len, DWORD access, int flags, off_t off);
+ int munmap (HANDLE h, caddr_t addr, size_t len);
+ int msync (HANDLE h, caddr_t addr, size_t len, int flags);
};
class fhandler_serial: public fhandler_base
@@ -777,8 +776,9 @@ public:
class fhandler_dev_mem: public fhandler_base
{
protected:
- unsigned long mem_size;
- unsigned long pos;
+ int unit;
+ DWORD mem_size;
+ DWORD pos;
bool init_phase;
void init (void);
@@ -795,6 +795,10 @@ public:
int fstat (struct stat *buf);
int dup (fhandler_base *child);
+ HANDLE mmap (caddr_t *addr, size_t len, DWORD access, int flags, off_t off);
+ int munmap (HANDLE h, caddr_t addr, size_t len);
+ int msync (HANDLE h, caddr_t addr, size_t len, int flags);
+
void dump ();
};
diff --git a/winsup/cygwin/fhandler_mem.cc b/winsup/cygwin/fhandler_mem.cc
index 10213e656..ae86f3f55 100644
--- a/winsup/cygwin/fhandler_mem.cc
+++ b/winsup/cygwin/fhandler_mem.cc
@@ -13,6 +13,7 @@
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
+#include <sys/mman.h>
#include <ntdef.h>
#include "autoload.h"
@@ -34,9 +35,10 @@ ULONG NTAPI RtlNtStatusToDosError(NTSTATUS);
/**********************************************************************/
/* fhandler_dev_mem */
-fhandler_dev_mem::fhandler_dev_mem (const char *name, int)
+fhandler_dev_mem::fhandler_dev_mem (const char *name, int nunit)
: fhandler_base (FH_MEM, name),
- init_phase(false)
+ unit (nunit),
+ init_phase (false)
{
}
@@ -47,24 +49,41 @@ fhandler_dev_mem::~fhandler_dev_mem (void)
void
fhandler_dev_mem::init ()
{
- long page_size = getpagesize ();
- char buf[1];
-
- init_phase = true;
- mem_size = pos = 1 << 30;
- for (off_t afct = 1 << 29; afct >= page_size; afct >>= 1)
+ if (unit == 1) /* /dev/mem */
{
- if (read (buf, 1) > 0)
- pos += afct;
- else
+ long page_size = getpagesize ();
+ char buf[1];
+
+ init_phase = true;
+ mem_size = pos = 1 << 30;
+ for (off_t afct = 1 << 29; afct >= page_size; afct >>= 1)
{
- if (pos < mem_size)
- mem_size = pos;
- pos -= afct;
+ if (read (buf, 1) > 0)
+ pos += afct;
+ else
+ {
+ if (pos < mem_size)
+ mem_size = pos;
+ pos -= afct;
+ }
}
+ pos = 0;
+ debug_printf ("MemSize: %d MB", mem_size >>= 20);
+ }
+ else if (unit == 2) /* /dev/kmem - Not yet supported */
+ {
+ mem_size = 0;
+ debug_printf ("KMemSize: %d MB", mem_size >>= 20);
+ }
+ else if (unit == 4) /* /dev/port == First 64K of /dev/mem */
+ {
+ mem_size = 65536;
+ debug_printf ("PortSize: 64 KB");
+ }
+ else
+ {
+ debug_printf ("Illegal unit!!!");
}
- pos = 0;
- debug_printf ("MemSize: %d MB", mem_size >>= 20);
init_phase = false;
}
@@ -74,7 +93,10 @@ fhandler_dev_mem::open (const char *, int flags, mode_t)
if (os_being_run != winNT)
{
set_errno (ENOENT);
- debug_printf ("/dev/mem is accessible under NT/W2K only");
+ debug_printf ("%s is accessible under NT/W2K only",
+ unit == 1 ? "/dev/mem" :
+ unit == 2 ? "/dev/kmem" :
+ "/dev/port" );
return 0;
}
@@ -167,7 +189,6 @@ fhandler_dev_mem::write (const void *ptr, size_t ulen)
}
pos += ulen;
-
return ulen;
}
@@ -217,7 +238,6 @@ fhandler_dev_mem::read (void *ptr, size_t ulen)
}
pos += ulen;
-
return ulen;
}
@@ -259,6 +279,105 @@ fhandler_dev_mem::lseek (off_t offset, int whence)
return pos;
}
+HANDLE
+fhandler_dev_mem::mmap (caddr_t *addr, size_t len, DWORD access,
+ int flags, off_t off)
+{
+ if ((DWORD) off >= mem_size
+ || (DWORD) len >= mem_size
+ || (DWORD) off + len >= mem_size)
+ {
+ set_errno (EINVAL);
+ syscall_printf ("-1 = mmap(): illegal parameter, set EINVAL");
+ return INVALID_HANDLE_VALUE;
+ }
+
+ UNICODE_STRING memstr;
+ RtlInitUnicodeString (&memstr, L"\\device\\physicalmemory");
+
+ OBJECT_ATTRIBUTES attr;
+ InitializeObjectAttributes(&attr, &memstr, OBJ_CASE_INSENSITIVE, NULL, NULL);
+
+ ACCESS_MASK section_access;
+ ULONG protect;
+
+ if (access & FILE_MAP_COPY)
+ {
+ section_access = SECTION_MAP_READ | SECTION_MAP_WRITE;
+ protect = PAGE_WRITECOPY;
+ }
+ else if (access & FILE_MAP_WRITE)
+ {
+ section_access = SECTION_MAP_READ | SECTION_MAP_WRITE;
+ protect = PAGE_READWRITE;
+ }
+ else
+ {
+ section_access = SECTION_MAP_READ;
+ protect = PAGE_READONLY;
+ }
+
+ HANDLE h;
+ NTSTATUS ret = NtOpenSection (&h, section_access, &attr);
+ if (!NT_SUCCESS(ret))
+ {
+ __seterrno_from_win_error (RtlNtStatusToDosError (ret));
+ syscall_printf ("-1 = mmap(): NtOpenSection failed with %E");
+ return INVALID_HANDLE_VALUE;
+ }
+
+ PHYSICAL_ADDRESS phys;
+ void *base = *addr;
+ DWORD dlen = len;
+
+ phys.QuadPart = (ULONGLONG) off;
+
+ if ((ret = NtMapViewOfSection (h,
+ INVALID_HANDLE_VALUE,
+ &base,
+ 0L,
+ dlen,
+ &phys,
+ &dlen,
+ ViewShare /*??*/,
+ 0,
+ protect)) != STATUS_SUCCESS)
+ {
+ __seterrno_from_win_error (RtlNtStatusToDosError (ret));
+ syscall_printf ("-1 = mmap(): NtMapViewOfSection failed with %E");
+ return INVALID_HANDLE_VALUE;
+ }
+ if ((flags & MAP_FIXED) && base != addr)
+ {
+ set_errno (EINVAL);
+ syscall_printf ("-1 = mmap(): address shift with MAP_FIXED given");
+ NtUnmapViewOfSection (INVALID_HANDLE_VALUE, base);
+ return INVALID_HANDLE_VALUE;
+ }
+
+ *addr = (caddr_t) base;
+ return h;
+}
+
+int
+fhandler_dev_mem::munmap (HANDLE h, caddr_t addr, size_t len)
+{
+ NTSTATUS ret;
+ if (!NT_SUCCESS(ret = NtUnmapViewOfSection (INVALID_HANDLE_VALUE, addr)))
+ {
+ __seterrno_from_win_error (RtlNtStatusToDosError (ret));
+ return -1;
+ }
+ CloseHandle (h);
+ return 0;
+}
+
+int
+fhandler_dev_mem::msync (HANDLE h, caddr_t addr, size_t len, int flags)
+{
+ return 0;
+}
+
int
fhandler_dev_mem::fstat (struct stat *buf)
{
@@ -276,7 +395,7 @@ fhandler_dev_mem::fstat (struct stat *buf)
S_IROTH | S_IWOTH;
buf->st_nlink = 1;
buf->st_blksize = getpagesize ();
- buf->st_dev = buf->st_rdev = get_device () << 8;
+ buf->st_dev = buf->st_rdev = get_device () << 8 | (unit & 0xff);
return 0;
}
diff --git a/winsup/cygwin/mmap.cc b/winsup/cygwin/mmap.cc
index 7c7d84c86..6beb45a2e 100644
--- a/winsup/cygwin/mmap.cc
+++ b/winsup/cygwin/mmap.cc
@@ -203,7 +203,7 @@ mmap (caddr_t addr, size_t len, int prot, int flags, int fd, off_t off)
caddr_t base = addr;
HANDLE h;
- if (fd == -1)
+ if ((flags & MAP_ANONYMOUS) || fd == -1)
{
fh_paging_file.set_io_handle (INVALID_HANDLE_VALUE);
fh = &fh_paging_file;
@@ -463,8 +463,16 @@ fhandler_disk_file::mmap (caddr_t *addr, size_t len, DWORD access,
if (!base || ((flags & MAP_FIXED) && base != addr))
{
- __seterrno ();
- syscall_printf ("-1 = mmap(): MapViewOfFileEx failed with %E");
+ if (!base)
+ {
+ __seterrno ();
+ syscall_printf ("-1 = mmap(): MapViewOfFileEx failed with %E");
+ }
+ else
+ {
+ set_errno (EINVAL);
+ syscall_printf ("-1 = mmap(): address shift with MAP_FIXED given");
+ }
CloseHandle (h);
return INVALID_HANDLE_VALUE;
}
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index 033a0c5c5..fb8bcd5dd 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -500,7 +500,15 @@ get_device_number (const char *name, int &unit, BOOL from_conv)
unit = 8 + (deveqn ("u", 1) ? 1 : 0); /* Keep unit Linux conformant */
}
else if (deveq ("mem"))
- devn = FH_MEM;
+ {
+ devn = FH_MEM;
+ unit = 1;
+ }
+ else if (deveq ("port"))
+ {
+ devn = FH_MEM;
+ unit = 4;
+ }
else if (deveqn ("com", 3) && (unit = digits (name + 3)) >= 0)
devn = FH_SERIAL;
else if (deveq ("pipe") || deveq ("piper") || deveq ("pipew"))