Merge pull request #690 from kareman/implement-FileHandle.nullDevice

diff --git a/Foundation/NSFileHandle.swift b/Foundation/NSFileHandle.swift
old mode 100644
new mode 100755
index 8596e66..dcc3e5d
--- a/Foundation/NSFileHandle.swift
+++ b/Foundation/NSFileHandle.swift
@@ -214,11 +214,49 @@
     open class var standardError: FileHandle {
         return _stderrFileHandle
     }
-    
+
+    internal static var _nulldeviceFileHandle: FileHandle = {
+        class NullDevice: FileHandle {
+            override var availableData: Data {
+                return Data()
+            }
+
+            override func readDataToEndOfFile() -> Data {
+                return Data()
+            }
+
+            override func readData(ofLength length: Int) -> Data {
+                return Data()
+            }
+
+            override func write(_ data: Data) {}
+
+            override var offsetInFile: UInt64 {
+                return 0
+            }
+
+            override func seekToEndOfFile() -> UInt64 {
+                return 0
+            }
+
+            override func seek(toFileOffset offset: UInt64) {}
+
+            override func truncateFile(atOffset offset: UInt64) {}
+
+            override func synchronizeFile() {}
+
+            override func closeFile() {}
+
+            deinit {}
+        }
+
+        return NullDevice(fileDescriptor: -1, closeOnDealloc: false)
+    }()
+
     open class var nullDevice: FileHandle {
-        NSUnimplemented()
+        return _nulldeviceFileHandle
     }
-    
+
     public convenience init?(forReadingAtPath path: String) {
         self.init(path: path, flags: O_RDONLY, createMode: 0)
     }
diff --git a/TestFoundation/TestNSFileHandle.swift b/TestFoundation/TestNSFileHandle.swift
old mode 100644
new mode 100755
index 69a74cc..93357ff
--- a/TestFoundation/TestNSFileHandle.swift
+++ b/TestFoundation/TestNSFileHandle.swift
@@ -19,6 +19,7 @@
     static var allTests : [(String, (TestNSFileHandle) -> () throws -> ())] {
         return [
                    ("test_pipe", test_pipe),
+                   ("test_nullDevice", test_nullDevice),
         ]
     }
 
@@ -38,4 +39,23 @@
             XCTAssertEqual(output, input)
         }
     }
+
+    func test_nullDevice() {
+        let fh = FileHandle.nullDevice
+
+        XCTAssertEqual(fh.fileDescriptor, -1)
+        fh.closeFile()
+        fh.seek(toFileOffset: 10)
+        XCTAssertEqual(fh.offsetInFile, 0)
+        XCTAssertEqual(fh.seekToEndOfFile(), 0)
+        XCTAssertEqual(fh.readData(ofLength: 15).count, 0)
+        fh.synchronizeFile()
+
+        fh.write(Data(bytes: [1,2]))
+        fh.seek(toFileOffset: 0)
+        XCTAssertEqual(fh.availableData.count, 0)
+        fh.write(Data(bytes: [1,2]))
+        fh.seek(toFileOffset: 0)
+        XCTAssertEqual(fh.readDataToEndOfFile().count, 0)
+    }
 }