Skip to content

Commit a459fc8

Browse files
committed
Add test for dirEntType
1 parent 1f571bc commit a459fc8

File tree

3 files changed

+130
-0
lines changed

3 files changed

+130
-0
lines changed

tests/DirEnt.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#include <dirent.h>
2+
#include <errno.h>
3+
#include <stdio.h>
4+
#include <stdlib.h>
5+
#include <string.h>
6+
#include <sys/types.h>
7+
8+
void check_error(const char *msg) {
9+
if (errno) {
10+
perror(msg);
11+
exit(1);
12+
}
13+
}
14+
15+
int main() {
16+
printf("Testing struct dirent d_type in C\n");
17+
int status = 0;
18+
19+
DIR *dir = opendir(".");
20+
check_error("opendir");
21+
22+
while (1) {
23+
struct dirent *de = readdir(dir);
24+
check_error("readdir");
25+
if (!de) {
26+
printf("Read the whole . dir without encountering \".\"!\n");
27+
status = 1;
28+
goto out;
29+
}
30+
31+
if (strcmp(de->d_name, ".") != 0) {
32+
continue;
33+
}
34+
// Otherwise, we found the . dir
35+
36+
if (de->d_type == DT_DIR) {
37+
// Signal that we should run test for non-zero d_type
38+
printf("Got DT_DIR for d_type for \".\"\n");
39+
goto out;
40+
} else if (de->d_type == DT_UNKNOWN) {
41+
printf("Got DT_UNKNOWN for d_type for \".\"\n");
42+
status = 2;
43+
goto out;
44+
} else {
45+
// . is something other than a directory. Shouldn't happen
46+
printf("Got %d for d_type for \".\"!", (int)de->d_type);
47+
status = 1;
48+
goto out;
49+
}
50+
}
51+
52+
out:
53+
closedir(dir);
54+
check_error("closedir");
55+
exit(status);
56+
}

tests/DirEnt.hs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
{-# LANGUAGE LambdaCase #-}
2+
3+
module Main (main) where
4+
5+
import Control.Exception (bracket)
6+
import Foreign.C.String (peekCString)
7+
import System.Exit
8+
import System.Posix.Directory
9+
import System.Posix.Directory.Internals
10+
import System.Process (system)
11+
12+
system_x :: String -> IO ExitCode
13+
system_x = system . ("set -x; " ++)
14+
15+
done :: IO a
16+
done = system_x "rm -f DirEnt-test" >> exitSuccess
17+
18+
peekDirEnt :: DirEnt -> IO (String, DirType)
19+
peekDirEnt dirEnt = do
20+
dName <- dirEntName dirEnt >>= peekCString
21+
dType <- dirEntType dirEnt
22+
return (dName, dType)
23+
24+
testDirTypeOfDot :: DirStream -> IO ()
25+
testDirTypeOfDot dirStream = go where
26+
go = do
27+
(dName, dType) <- readDirStreamWith peekDirEnt dirStream >>= maybe
28+
(die "Read cwd in Haskell and didn't find . dir!")
29+
return
30+
31+
case dName of
32+
"." -> case dType of
33+
DirectoryType -> putStrLn "Got DirectoryType for . dir" >> done
34+
_ -> die $ "Got " ++ show dType ++ " for . dir!"
35+
_ -> go
36+
37+
main :: IO ()
38+
main = do
39+
putStrLn "Preparing Haskell test of dirEntType"
40+
41+
system_x "cc --version" >>= \case
42+
ExitSuccess -> return ()
43+
ec -> exitWith ec
44+
45+
system_x "[ -f tests/DirEnt.c ]" >>= \case
46+
ExitSuccess -> return ()
47+
ec -> do
48+
putStrLn "Not running tests from root of repo?"
49+
exitWith ec
50+
51+
system_x "cc tests/DirEnt.c -o DirEnt-test" >>= \case
52+
ExitSuccess -> return ()
53+
ExitFailure _ -> do
54+
putStrLn "d_type not available? Skipping Haskell test"
55+
done
56+
57+
-- As written, this C code exits with 2 if it determines the Haskell test
58+
-- for broken dirEntType will be a false positive
59+
system_x "./DirEnt-test" >>= \case
60+
ExitSuccess -> return ()
61+
ExitFailure 2 -> putStrLn "Skipping Haskell test" >> done
62+
ec -> exitWith ec
63+
64+
putStrLn "Running Haskell test of dirEntType"
65+
66+
bracket (openDirStream "/home/steve/foo") closeDirStream testDirTypeOfDot

unix.cabal

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,3 +382,11 @@ test-suite T13660
382382
else
383383
build-depends: filepath >= 1.4.100.0 && < 1.5.0.0
384384
ghc-options: -Wall
385+
386+
test-suite DirEnt
387+
hs-source-dirs: tests
388+
main-is: DirEnt.hs
389+
type: exitcode-stdio-1.0
390+
default-language: Haskell2010
391+
build-depends: base, unix, process
392+
ghc-options: -Wall

0 commit comments

Comments
 (0)