NativeIO { public static String getOwner(FileDescriptor fd) throws IOException { ensureInitialized(); if (Shell.WINDOWS) { String owner = Windows.getOwner(fd); owner = stripDomain(owner); return owner; } else { long uid = POSIX.getUIDforFDOwnerforOwner(fd); CachedUid cUid = uidCache.get(uid); long now = System.currentTimeMillis(); if (cUid != null && (cUid.timestamp + cacheTimeout) > now) { return cUid.username; } String user = POSIX.getUserName(uid); LOG.info("Got UserName " + user + " for UID " + uid + " from the native implementation"); cUid = new CachedUid(user, now); uidCache.put(uid, cUid); return user; } }  static boolean isAvailable(); static String getOwner(FileDescriptor fd); static FileDescriptor getShareDeleteFileDescriptor(
      File f, long seekOffset); static FileOutputStream getCreateForWriteFileOutputStream(File f, int permissions); static void renameTo(File src, File dst); @Deprecated static void link(File src, File dst); static void copyFileUnbuffered(File src, File dst);  }
@Test (timeout = 30000) public void testFstat() throws Exception { FileOutputStream fos = new FileOutputStream( new File(TEST_DIR, "testfstat")); NativeIO.POSIX.Stat stat = NativeIO.POSIX.getFstat(fos.getFD()); fos.close(); LOG.info("Stat: " + String.valueOf(stat)); String owner = stat.getOwner(); String expectedOwner = System.getProperty("user.name"); if (Path.WINDOWS) { UserGroupInformation ugi = UserGroupInformation.createRemoteUser(expectedOwner); final String adminsGroupString = "Administrators"; if (Arrays.asList(ugi.getGroupNames()).contains(adminsGroupString)) { expectedOwner = adminsGroupString; } } assertEquals(expectedOwner, owner); assertNotNull(stat.getGroup()); assertTrue(!stat.getGroup().isEmpty()); assertEquals("Stat mode field should indicate a regular file", S_IFREG, stat.getMode() & S_IFMT); }
@Test (timeout = 30000) public void testMultiThreadedFstat() throws Exception { assumeNotWindows(); final FileOutputStream fos = new FileOutputStream( new File(TEST_DIR, "testfstat")); final AtomicReference<Throwable> thrown = new AtomicReference<Throwable>(); List<Thread> statters = new ArrayList<Thread>(); for (int i = 0; i < 10; i++) { Thread statter = new Thread() { @Override public void run() { long et = Time.now() + 5000; while (Time.now() < et) { try { NativeIO.POSIX.Stat stat = NativeIO.POSIX.getFstat(fos.getFD()); assertEquals(System.getProperty("user.name"), stat.getOwner()); assertNotNull(stat.getGroup()); assertTrue(!stat.getGroup().isEmpty()); assertEquals("Stat mode field should indicate a regular file", S_IFREG, stat.getMode() & S_IFMT); } catch (Throwable t) { thrown.set(t); } } } }; statters.add(statter); statter.start(); } for (Thread t : statters) { t.join(); } fos.close(); if (thrown.get() != null) { throw new RuntimeException(thrown.get()); } }