diff --git a/current.spec b/current.spec
index 8e8592a75d2cd6494d350fddf8fc0c7eea8f0835..b9b1341abdaed059428b7dc5814d6a2aec21373b 100644
--- a/current.spec
+++ b/current.spec
@@ -1,11 +1,11 @@
 Summary: An fdisk-like partitioning tool for GPT disks
 Name: gdisk
-Version: 0.6.7
+Version: 0.6.8
 Release: 1%{?dist}
 License: GPLv2
 URL: http://www.rodsbooks.com/gdisk
 Group: Applications/System
-Source: http://www.rodsbooks.com/gdisk/gdisk-0.6.7.tgz
+Source: http://www.rodsbooks.com/gdisk/gdisk-0.6.8.tgz
 BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
 
 %description
@@ -34,11 +34,11 @@ rm -rf $RPM_BUILD_ROOT
 
 %files
 %defattr(-,root,root -)
-%doc CHANGELOG COPYING README
+%doc NEWS COPYING README
 /sbin/gdisk
 /sbin/sgdisk
 %doc %{_mandir}/man8*
 
 %changelog
-* Sat May 1 2010 R Smith <rodsmith@rodsbooks.com> - 0.6.7
-- Created spec file for 0.6.7 release
+* Sun May 23 2010 R Smith <rodsmith@rodsbooks.com> - 0.6.8
+- Created spec file for 0.6.8 release
diff --git a/diskio-unix.cc b/diskio-unix.cc
index 7d24301e7b63696b6d3806ad478b0bd696785dc4..b20f1614234d9279e8dcd2688a6532640bd1bcc1 100644
--- a/diskio-unix.cc
+++ b/diskio-unix.cc
@@ -39,6 +39,7 @@ void DiskIO::MakeRealName(void) {
 // work.
 int DiskIO::OpenForRead(void) {
    int shouldOpen = 1;
+   struct stat64 st;
 
    if (isOpen) { // file is already open
       if (openForWrite) {
@@ -61,8 +62,22 @@ int DiskIO::OpenForRead(void) {
          isOpen = 0;
          openForWrite = 0;
       } else {
-         isOpen = 1;
+         isOpen = 0;
          openForWrite = 0;
+         if (fstat64(fd, &st) == 0) {
+            if (S_ISDIR(st.st_mode))
+               cerr << "The specified path is a directory!\n";
+#ifndef __FreeBSD__
+            else if (S_ISCHR(st.st_mode))
+               cerr << "The specified path is a character device!\n";
+#endif
+            else if (S_ISFIFO(st.st_mode))
+               cerr << "The specified path is a FIFO!\n";
+            else if (S_ISSOCK(st.st_mode))
+               cerr << "The specified path is a socket!\n";
+            else
+               isOpen = 1;
+         } // if (fstat64()...)
       } // if/else
    } // if
 
diff --git a/gdisk.8 b/gdisk.8
index 1a93c38df20b846ca9253c47f6541265ba431154..ce4cda8237cbe150dbdc7e53e95dad17d2ba26a9 100644
--- a/gdisk.8
+++ b/gdisk.8
@@ -1,6 +1,6 @@
 .\" Copyright 2010 Roderick W. Smith (rodsmith@rodsbooks.com)
 .\" May be distributed under the GNU General Public License
-.TH "GDISK" "8" "0.6.7" "Roderick W. Smith" "GPT fdisk Manual"
+.TH "GDISK" "8" "0.6.8" "Roderick W. Smith" "GPT fdisk Manual"
 .SH "NAME"
 gdisk \- Interactive GUID partition table (GPT) manipulator
 .SH "SYNOPSIS"
@@ -648,6 +648,8 @@ Contributors:
 
 * David Hubbard (david.c.hubbard@gmail.com)
 
+* One anonymous contributor
+
 .SH "SEE ALSO"
 \fBcfdisk (8)\fR,
 \fBfdisk (8)\fR,
diff --git a/gpt.cc b/gpt.cc
index 429203553b18ee622258eb09cb32f7a7fe31e398..213774ed44a7599a33fbfcf0faff42a076b42a31 100644
--- a/gpt.cc
+++ b/gpt.cc
@@ -30,10 +30,13 @@
 
 using namespace std;
 
-#ifdef __FreeBSD__ 
+#ifdef __FreeBSD__
 #define log2(x) (log(x) / M_LN2)
 #endif // __FreeBSD__
 
+#ifdef _MSC_VER
+#define log2(x) (log((double) x) / log(2.0))
+#endif // Microsoft Visual C++
 
 /****************************************
  *                                      *
diff --git a/gpt.h b/gpt.h
index f2399b4f289c237e580aac69c7463232f9356139..235c7affd345a3b0f3d8a6da5606af21a78942df 100644
--- a/gpt.h
+++ b/gpt.h
@@ -16,7 +16,7 @@
 #ifndef __GPTSTRUCTS
 #define __GPTSTRUCTS
 
-#define GPTFDISK_VERSION "0.6.8-pre2"
+#define GPTFDISK_VERSION "0.6.8"
 
 // Constants used by GPTData::PartsToMBR(). MBR_EMPTY must be the lowest-
 // numbered value to refer to partition numbers. (Most will be 0 or positive,
diff --git a/guid.cc b/guid.cc
index 07fd733f0ef73dc4bf93c25c4d1195d743559511..9a55765f7f97b2e084595451e68c3f967b87f201 100644
--- a/guid.cc
+++ b/guid.cc
@@ -55,6 +55,8 @@ GUIDData & GUIDData::operator=(const GUIDData & orig) {
 // than 36 characters long, this function assumes the input GUID has
 // been compressed by removal of separators. In either event, there's
 // little in the way of sanity checking, so garbage in = garbage out!
+// One special case: If the first character is 'r' or 'R', a random
+// GUID is assigned.
 GUIDData & GUIDData::operator=(const string & orig) {
    string copy, fragment;
    size_t len;
@@ -63,45 +65,51 @@ GUIDData & GUIDData::operator=(const string & orig) {
    size_t shortSegs[6] = {0, 8, 12, 16, 20, 32};
    size_t *segStart = longSegs; // Assume there are separators between segments
 
-   Zero();
-
-   // Delete stray spaces....
-   copy = DeleteSpaces(orig);
-
-   // If length is too short, assume there are no separators between segments
-   len = copy.length();
-   if (len < 36) {
-      segStart = shortSegs;
-   };
-
-   // Extract data fragments at fixed locations and convert to
-   // integral types....
-   if (len >= segStart[1]) {
-      uuidData[3] = StrToHex(copy, 0);
-      uuidData[2] = StrToHex(copy, 2);
-      uuidData[1] = StrToHex(copy, 4);
-      uuidData[0] = StrToHex(copy, 6);
-   } // if
-   if (len >= segStart[2]) {
-      uuidData[5] = StrToHex(copy, segStart[1]);
-      uuidData[4] = StrToHex(copy, segStart[1] + 2);
-   } // if
-   if (len >= segStart[3]) {
-      uuidData[7] = StrToHex(copy, segStart[2]);
-      uuidData[6] = StrToHex(copy, segStart[2] + 2);
-   } // if
-   if (len >= segStart[4]) {
-      uuidData[8] = StrToHex(copy, segStart[3]);
-      uuidData[9] = StrToHex(copy, segStart[3] + 2);
-   } // if
-   if (len >= segStart[5]) {
-      uuidData[10] = StrToHex(copy, segStart[4]);
-      uuidData[11] = StrToHex(copy, segStart[4] + 2);
-      uuidData[12] = StrToHex(copy, segStart[4] + 4);
-      uuidData[13] = StrToHex(copy, segStart[4] + 6);
-      uuidData[14] = StrToHex(copy, segStart[4] + 8);
-      uuidData[15] = StrToHex(copy, segStart[4] + 10);
-   } // if
+   // If first character is an 'R' or 'r', set a random GUID; otherwise,
+   // try to parse it as a real GUID
+   if ((orig[0] == 'R') || (orig[0] == 'r')) {
+      Randomize();
+   } else {
+      Zero();
+
+      // Delete stray spaces....
+      copy = DeleteSpaces(orig);
+
+      // If length is too short, assume there are no separators between segments
+      len = copy.length();
+      if (len < 36) {
+         segStart = shortSegs;
+      };
+
+      // Extract data fragments at fixed locations and convert to
+      // integral types....
+      if (len >= segStart[1]) {
+         uuidData[3] = StrToHex(copy, 0);
+         uuidData[2] = StrToHex(copy, 2);
+         uuidData[1] = StrToHex(copy, 4);
+         uuidData[0] = StrToHex(copy, 6);
+      } // if
+      if (len >= segStart[2]) {
+         uuidData[5] = StrToHex(copy, segStart[1]);
+         uuidData[4] = StrToHex(copy, segStart[1] + 2);
+      } // if
+      if (len >= segStart[3]) {
+         uuidData[7] = StrToHex(copy, segStart[2]);
+         uuidData[6] = StrToHex(copy, segStart[2] + 2);
+      } // if
+      if (len >= segStart[4]) {
+         uuidData[8] = StrToHex(copy, segStart[3]);
+         uuidData[9] = StrToHex(copy, segStart[3] + 2);
+      } // if
+      if (len >= segStart[5]) {
+         uuidData[10] = StrToHex(copy, segStart[4]);
+         uuidData[11] = StrToHex(copy, segStart[4] + 2);
+         uuidData[12] = StrToHex(copy, segStart[4] + 4);
+         uuidData[13] = StrToHex(copy, segStart[4] + 6);
+         uuidData[14] = StrToHex(copy, segStart[4] + 8);
+         uuidData[15] = StrToHex(copy, segStart[4] + 10);
+      } // if
+   } // if/else randomize/set value
 
    return *this;
 } // GUIDData::operator=(const string & orig)
diff --git a/sgdisk.8 b/sgdisk.8
index 6a3a0b1e6d238fe4344df59a288e57b0401eb9ac..63c8cf5980990e9ec628c5a27c91584215217480 100644
--- a/sgdisk.8
+++ b/sgdisk.8
@@ -1,6 +1,6 @@
 .\" Copyright 2010 Roderick W. Smith (rodsmith@rodsbooks.com)
 .\" May be distributed under the GNU General Public License
-.TH "SGDISK" "8" "0.6.7" "Roderick W. Smith" "GPT fdisk Manual"
+.TH "SGDISK" "8" "0.6.8" "Roderick W. Smith" "GPT fdisk Manual"
 .SH "NAME"
 sgdisk \- Command\-line GUID partition table (GPT) manipulator for Linux and Unix
 .SH "SYNOPSIS"
@@ -365,11 +365,13 @@ high compared to the likelihood of problems with an MBR conversion.
 
 .TP
 .B \-u, \-\-partition-guid=partnum:guid
-Set the partition unique GUID for an individual partition.
+Set the partition unique GUID for an individual partition. The GUID may be
+a complete GUID or 'R' to set a random GUID.
 
 .TP
 .B \-U, \-\-disk-guid=guid
-Set the GUID for the disk.
+Set the GUID for the disk. The GUID may be a complete GUID or 'R' to set a
+random GUID.
 
 .TP 
 .B \-\-usage
@@ -530,6 +532,8 @@ Contributors:
 
 * David Hubbard (david.c.hubbard@gmail.com)
 
+* One anonymous contributor
+
 .SH "SEE ALSO"
 \fBcfdisk (8)\fR,
 \fBfdisk (8)\fR,