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
67
68
69
70
71
72
73
|
#+private
#+build darwin, netbsd, freebsd, openbsd
package os
import "core:sys/posix"
import "core:strings"
_pipe :: proc() -> (r, w: ^File, err: Error) {
fds: [2]posix.FD
if posix.pipe(&fds) != .OK {
err = _get_platform_error()
return
}
if posix.fcntl(fds[0], .SETFD, i32(posix.FD_CLOEXEC)) == -1 {
err = _get_platform_error()
return
}
if posix.fcntl(fds[1], .SETFD, i32(posix.FD_CLOEXEC)) == -1 {
err = _get_platform_error()
return
}
r = __new_file(fds[0], file_allocator())
ri := (^File_Impl)(r.impl)
rname := strings.builder_make(file_allocator())
// TODO(laytan): is this on all the posix targets?
strings.write_string(&rname, "/dev/fd/")
strings.write_int(&rname, int(fds[0]))
ri.name = strings.to_string(rname)
ri.cname = strings.to_cstring(&rname) or_return
w = __new_file(fds[1], file_allocator())
wi := (^File_Impl)(w.impl)
wname := strings.builder_make(file_allocator())
// TODO(laytan): is this on all the posix targets?
strings.write_string(&wname, "/dev/fd/")
strings.write_int(&wname, int(fds[1]))
wi.name = strings.to_string(wname)
wi.cname = strings.to_cstring(&wname) or_return
return
}
@(require_results)
_pipe_has_data :: proc(r: ^File) -> (ok: bool, err: Error) {
if r == nil || r.impl == nil {
return false, nil
}
fd := __fd(r)
poll_fds := []posix.pollfd {
posix.pollfd {
fd = fd,
events = {.IN, .HUP},
},
}
n := posix.poll(raw_data(poll_fds), u32(len(poll_fds)), 0)
if n < 0 {
return false, _get_platform_error()
} else if n != 1 {
return false, nil
}
pipe_events := poll_fds[0].revents
if pipe_events >= {.IN} {
return true, nil
}
if pipe_events >= {.HUP} {
return false, .Broken_Pipe
}
return false, nil
}
|