summaryrefslogtreecommitdiff
path: root/lib/std/dir+linux.myr
blob: 60ef6f90de9ff74751b171b85be3f14d474a684b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
use sys

use "alloc.use"
use "die.use"
use "option.use"
use "result.use"
use "slcp.use"
use "sldup.use"
use "types.use"

pkg std =
	type dir = struct
		fd	: sys.fd
		buf	: byte[16384]
		len	: int64
		off	: int64
	;;

	const diropen	: (p : byte[:] -> std.result(dir#, byte[:]))
	const dirread	: (d : dir# -> std.option(byte[:]))
	const dirclose	: (d : dir# -> void)
;;

const Direntoverhead = 20

const diropen = {p
	var fd
	var dir

	fd = sys.open(p, sys.Ordonly | sys.Odir)
	if fd < 0
		-> `Fail "couldn't open directory"
	;;
	dir = zalloc()
	dir.fd = fd
	-> `Ok dir
}

const dirread = {d
	var len
	var dent
	var namelen

	if d.off >= d.len
		len = sys.getdents64(d.fd, d.buf[:])
		if len <= 0
			-> `None
		;;
		d.len = len
		d.off = 0
	;;

	dent = &d.buf[d.off] castto(sys.dirent64#)
	namelen = 0
	d.off += dent.reclen castto(int64)
	while dent.name[namelen] != 0
		namelen++
	;;
	-> `Some sldup(dent.name[:namelen])
}

const dirclose = {d
	sys.close(d.fd)
	free(d)
}