From 1c0c369b36c1ddf4af25052b311a48597b5fdb3f Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 3 May 2000 15:39:10 +0000 Subject: [PATCH] * Makefile.in: Add dependencies for fhandler_random.o * fhandler.h: Add device type FH_RANDOM. Add class fhandler_dev_random. * fhandler_random.cc: New file. Implementation of fhandler_dev_random. * hinfo.cc (build_fhandler): Add case for FH_RANDOM. * path.cc: Add device names for random devices to windows_device_names. (get_device_number): Add if branch for random devices. (win32_device_name): Add device name generation for random devices. winsup.h: Include . --- winsup/cygwin/ChangeLog | 15 ++++++ winsup/cygwin/Makefile.in | 4 +- winsup/cygwin/dtable.cc | 3 ++ winsup/cygwin/fhandler.h | 21 +++++++- winsup/cygwin/fhandler_random.cc | 92 ++++++++++++++++++++++++++++++++ winsup/cygwin/path.cc | 11 +++- winsup/cygwin/winsup.h | 1 + 7 files changed, 144 insertions(+), 3 deletions(-) create mode 100644 winsup/cygwin/fhandler_random.cc diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 9c7cd2654..617931a9a 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,18 @@ +Wed May 3 17:28:00 2000 Corinna Vinschen + + * Makefile.in: Add dependencies for fhandler_random.o + * fhandler.h: Add device type FH_RANDOM. Add class + fhandler_dev_random. + * fhandler_random.cc: New file. Implementation of + fhandler_dev_random. + * hinfo.cc (build_fhandler): Add case for FH_RANDOM. + * path.cc: Add device names for random devices to + windows_device_names. + (get_device_number): Add if branch for random devices. + (win32_device_name): Add device name generation for + random devices. + winsup.h: Include . + 2000-05-02 Kazuhiro Fujieda * path.cc (mount_info::conv_to_win32_path): Previous patch diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in index 117944f06..a565d5555 100644 --- a/winsup/cygwin/Makefile.in +++ b/winsup/cygwin/Makefile.in @@ -119,7 +119,8 @@ DLL_IMPORTS:=$(w32api_lib)/libkernel32.a $(w32api_lib)/libadvapi32.a DLL_OFILES:=assert.o dcrt0.o debug.o delqueue.o dir.o dlfcn.o dll_init.o \ environ.o errno.o exceptions.o exec.o external.o fcntl.o fhandler.o \ fhandler_console.o fhandler_serial.o fhandler_termios.o fhandler_tty.o \ - fhandler_windows.o fhandler_raw.o fhandler_floppy.o fhandler_tape.o fhandler_zero.o \ + fhandler_windows.o fhandler_raw.o fhandler_floppy.o fhandler_tape.o \ + fhandler_zero.o fhandler_random.o \ fork.o glob.o grp.o heap.o hinfo.o init.o ioctl.o localtime.o malloc.o \ mmap.o net.o ntea.o passwd.o path.o pinfo.o pipe.o regexp.o regerror.o \ regsub.o registry.o resource.o scandir.o security.o select.o shared.o \ @@ -292,6 +293,7 @@ fhandler_raw.o: $(WINSUP_H) fhandler_floppy.o: $(WINSUP_H) fhandler_tape.o: $(WINSUP_H) fhandler_zero.o: $(WINSUP_H) +fhandler_random.o: $(WINSUP_H) fork.o: $(WINSUP_H) dll_init.h glob.o: include/glob.h gmon.o: profil.h gmon.h diff --git a/winsup/cygwin/dtable.cc b/winsup/cygwin/dtable.cc index f3dd1fb94..40d31a920 100644 --- a/winsup/cygwin/dtable.cc +++ b/winsup/cygwin/dtable.cc @@ -282,6 +282,9 @@ hinfo::build_fhandler (int fd, DWORD dev, const char *name, int unit) case FH_ZERO: fh = new (buf) fhandler_dev_zero (name); break; + case FH_RANDOM: + fh = new (buf) fhandler_dev_random (name, unit); + break; default: /* FIXME - this could recurse forever */ return build_fhandler (fd, name, NULL); diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 61e033931..e81085ad7 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -91,8 +91,9 @@ enum FH_TAPE = 0x00000012, /* is a tape */ FH_NULL = 0x00000013, /* is the null device */ FH_ZERO = 0x00000014, /* is the zero device */ + FH_RANDOM = 0x00000015, /* is a random device */ - FH_NDEV = 0x00000015, /* Maximum number of devices */ + FH_NDEV = 0x00000016, /* Maximum number of devices */ FH_DEVMASK = 0x00000fff, /* devices live here */ FH_BAD = 0xffffffff }; @@ -732,6 +733,24 @@ public: void dump (); }; +class fhandler_dev_random: public fhandler_base +{ +protected: + int unit; + HCRYPTPROV crypt_prov; +public: + fhandler_dev_random (const char *name, int unit); + int get_unit () { return unit; } + int open (const char *path, int flags, mode_t mode = 0); + int write (const void *ptr, size_t len); + int read (void *ptr, size_t len); + off_t lseek (off_t offset, int whence); + int close (void); + int dup (fhandler_base *child); + + void dump (); +}; + class fhandler_windows: public fhandler_base { private: diff --git a/winsup/cygwin/fhandler_random.cc b/winsup/cygwin/fhandler_random.cc new file mode 100644 index 000000000..6ea72fa0d --- /dev/null +++ b/winsup/cygwin/fhandler_random.cc @@ -0,0 +1,92 @@ +/* fhandler_dev_random.cc: code to access /dev/random + + Copyright 2000 Cygnus Solutions. + + Written by Corinna Vinschen (vinschen@cygnus.com) + +This file is part of Cygwin. + +This software is a copyrighted work licensed under the terms of the +Cygwin license. Please consult the file "CYGWIN_LICENSE" for +details. */ + +#include +#include "winsup.h" + +#define RANDOM 8 +#define URANDOM 9 + +fhandler_dev_random::fhandler_dev_random (const char *name, int nunit) + : fhandler_base (FH_RANDOM, name), + unit(nunit), + crypt_prov((HCRYPTPROV)NULL) +{ + set_cb (sizeof *this); +} + +int +fhandler_dev_random::open (const char *, int flags, mode_t) +{ + set_flags (flags); + return 1; +} + +int +fhandler_dev_random::write (const void *, size_t len) +{ + return len; +} + +int +fhandler_dev_random::read (void *ptr, size_t len) +{ + if (!len) + return 0; + if (!crypt_prov + && !CryptAcquireContext (&crypt_prov, NULL, MS_DEF_PROV, + PROV_RSA_FULL, 0) + && !CryptAcquireContext (&crypt_prov, NULL, MS_DEF_PROV, + PROV_RSA_FULL, CRYPT_NEWKEYSET)) + { + __seterrno (); + return -1; + } + if (!CryptGenRandom (crypt_prov, len, (BYTE *)ptr)) + { + __seterrno (); + return -1; + } + return len; +} + +off_t +fhandler_dev_random::lseek (off_t, int) +{ + return 0; +} + +int +fhandler_dev_random::close (void) +{ + if (crypt_prov) + while (!CryptReleaseContext (crypt_prov, 0) + && GetLastError () == ERROR_BUSY) + Sleep(10); + return 0; +} + +int +fhandler_dev_random::dup (fhandler_base *child) +{ + fhandler_dev_random *fhr = (fhandler_dev_random *) child; + fhr->unit = unit; + fhr->crypt_prov = (HCRYPTPROV)NULL; + return 0; +} + +void +fhandler_dev_random::dump () +{ + paranoid_printf("here, fhandler_dev_random"); +} + diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index c9f9b4af4..15194e937 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -436,6 +436,7 @@ const char *windows_device_names[] = "\\dev\\st%d", "nul", "\\dev\\zero", + "\\dev\\%srandom", }; static int @@ -500,6 +501,11 @@ get_device_number (const char *name, int &unit, BOOL from_conv) devn = FH_NULL; else if (deveq ("zero")) devn = FH_ZERO; + else if (deveq ("random") || deveq ("urandom")) + { + devn = FH_RANDOM; + unit = 8 + (deveqn ("u", 1) ? 1 : 0); /* Keep unit Linux conformant */ + } else if (deveqn ("com", 3) && (unit = digits (name + 3)) >= 0) devn = FH_SERIAL; else if (deveq ("pipe") || deveq ("piper") || deveq ("pipew")) @@ -535,7 +541,10 @@ win32_device_name (const char *src_path, char *win32_path, if ((devfmt = windows_device_names[FHDEVN (devn)]) == NULL) return FALSE; - __small_sprintf (win32_path, devfmt, unit); + if (devn == FH_RANDOM) + __small_sprintf (win32_path, devfmt, unit == 8 ? "" : "u"); + else + __small_sprintf (win32_path, devfmt, unit); return TRUE; } diff --git a/winsup/cygwin/winsup.h b/winsup/cygwin/winsup.h index 68fc14702..76688a743 100644 --- a/winsup/cygwin/winsup.h +++ b/winsup/cygwin/winsup.h @@ -51,6 +51,7 @@ return __res; } #include +#include /* Used for runtime OS check/decisions. */ enum os_type {winNT = 1, win95, win98, win32s, unknown};