Skip to content

Commit dc96eb9

Browse files
authored
os: add Pipe.write_string/1 (#26286)
1 parent 1e9f977 commit dc96eb9

3 files changed

Lines changed: 62 additions & 75 deletions

File tree

‎vlib/os/notify/notify_test.c.v‎

Lines changed: 36 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -3,34 +3,21 @@
33
import os
44
import os.notify
55

6-
// make a pipe and return the (read, write) file descriptors
7-
fn make_pipe() !(int, int) {
8-
$if linux || macos {
9-
pipefd := [2]int{}
10-
if C.pipe(&pipefd[0]) != 0 {
11-
return error('error ${C.errno}: ' + os.posix_get_error_msg(C.errno))
12-
}
13-
return pipefd[0], pipefd[1]
14-
}
15-
return -1, -1
16-
}
17-
186
fn test_level_trigger() {
197
// currently only linux and macos are supported
208
$if linux || macos {
219
mut notifier := notify.new()!
22-
reader, writer := make_pipe()!
10+
mut pipe := os.pipe()!
2311
defer {
24-
os.fd_close(reader)
25-
os.fd_close(writer)
12+
pipe.close()
2613
notifier.close() or {}
2714
}
28-
notifier.add(reader, .read)!
15+
notifier.add(pipe.read_fd, .read)!
2916

30-
os.fd_write(writer, 'foobar')
17+
pipe.write_string('foobar')!
3118
mut n := &notifier
32-
check_read_event(mut n, reader, 'foo')
33-
check_read_event(mut n, reader, 'bar')
19+
check_read_event(mut n, pipe.read_fd, 'foo')
20+
check_read_event(mut n, pipe.read_fd, 'bar')
3421

3522
assert notifier.wait(0).len == 0
3623
}
@@ -40,18 +27,17 @@ fn test_edge_trigger() {
4027
// currently only linux and macos are supported
4128
$if linux || macos {
4229
mut notifier := notify.new()!
43-
reader, writer := make_pipe()!
30+
mut pipe := os.pipe()!
4431
defer {
45-
os.fd_close(reader)
46-
os.fd_close(writer)
32+
pipe.close()
4733
notifier.close() or {}
4834
}
49-
notifier.add(reader, .read, .edge_trigger)!
35+
notifier.add(pipe.read_fd, .read, .edge_trigger)!
5036

5137
mut n := &notifier
5238

53-
os.fd_write(writer, 'foobar')
54-
check_read_event(mut n, reader, 'foo')
39+
pipe.write_string('foobar')!
40+
check_read_event(mut n, pipe.read_fd, 'foo')
5541

5642
$if linux {
5743
assert notifier.wait(0).len == 0
@@ -75,7 +61,8 @@ fn test_edge_trigger() {
7561
// notifier.wait(0).len == 1 or 0
7662
}
7763

78-
os.fd_write(writer, 'baz')
64+
pipe.write_string('baz')!
65+
check_read_event(mut n, pipe.read_fd, 'barbaz')
7966
// we do not get an event because there is still data
8067
// to be read
8168
// assert notifier.wait(0).len == 0
@@ -87,90 +74,87 @@ fn test_edge_trigger() {
8774
fn test_one_shot() {
8875
$if linux || macos {
8976
mut notifier := notify.new()!
90-
reader, writer := make_pipe()!
77+
mut pipe := os.pipe()!
9178
defer {
92-
os.fd_close(reader)
93-
os.fd_close(writer)
79+
pipe.close()
9480
notifier.close() or {}
9581
}
96-
notifier.add(reader, .read, .one_shot)!
82+
notifier.add(pipe.read_fd, .read, .one_shot)!
9783

9884
mut n := &notifier
9985

100-
os.fd_write(writer, 'foobar')
101-
check_read_event(mut n, reader, 'foo')
102-
os.fd_write(writer, 'baz')
86+
pipe.write_string('foobar')!
87+
check_read_event(mut n, pipe.read_fd, 'foo')
88+
pipe.write_string('baz')!
10389

10490
assert notifier.wait(0).len == 0
10591

10692
// rearm
107-
notifier.modify(reader, .read)!
108-
check_read_event(mut n, reader, 'barbaz')
93+
notifier.modify(pipe.read_fd, .read)!
94+
check_read_event(mut n, pipe.read_fd, 'barbaz')
10995
}
11096
}
11197

11298
// Kqueue does not support 'hangup' event type.
11399
fn test_hangup() {
114100
$if linux {
115101
mut notifier := notify.new()!
116-
reader, writer := make_pipe()!
102+
mut pipe := os.pipe()!
117103
defer {
118-
os.fd_close(reader)
104+
os.fd_close(pipe.read_fd)
119105
notifier.close() or {}
120106
}
121-
notifier.add(reader, .hangup)!
107+
notifier.add(pipe.read_fd, .hangup)!
122108

123109
assert notifier.wait(0).len == 0
124110

125111
// closing on the writer end of the pipe will
126112
// cause a hangup on the reader end
127-
os.fd_close(writer)
113+
os.fd_close(pipe.write_fd)
128114
events := notifier.wait(0)
129115
assert events.len == 1
130-
assert events[0].fd == reader
116+
assert events[0].fd == pipe.read_fd
131117
assert events[0].kind.has(.hangup)
132118
}
133119
}
134120

135121
fn test_write() {
136122
$if linux || macos {
137123
mut notifier := notify.new()!
138-
reader, writer := make_pipe()!
124+
mut pipe := os.pipe()!
139125
defer {
140-
os.fd_close(reader)
141-
os.fd_close(writer)
126+
pipe.close()
142127
notifier.close() or {}
143128
}
144129

145-
notifier.add(reader, .write)!
130+
notifier.add(pipe.read_fd, .write)!
146131
assert notifier.wait(0).len == 0
147132

148-
notifier.add(writer, .write)!
133+
notifier.add(pipe.write_fd, .write)!
149134
events := notifier.wait(0)
150135
assert events.len == 1
151-
assert events[0].fd == writer
136+
assert events[0].fd == pipe.write_fd
152137
assert events[0].kind.has(.write)
153138
}
154139
}
155140

156141
fn test_remove() {
157142
$if linux || macos {
158143
mut notifier := notify.new()!
159-
reader, writer := make_pipe()!
144+
mut pipe := os.pipe()!
160145
defer {
161-
os.fd_close(reader)
162-
os.fd_close(writer)
146+
pipe.close()
163147
notifier.close() or {}
164148
}
165149

166150
// level triggered - will keep getting events while
167151
// there is data to read
168-
notifier.add(reader, .read)!
169-
os.fd_write(writer, 'foobar')
152+
notifier.add(pipe.read_fd, .read)!
153+
pipe.write_string('foobar')!
170154
assert notifier.wait(0).len == 1
171155
assert notifier.wait(0).len == 1
172156

173-
notifier.remove(reader)!
157+
notifier.remove(pipe.read_fd)!
174158
assert notifier.wait(0).len == 0
175159
}
176160
}

‎vlib/os/pipe.c.v‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ pub fn fd_dup2(fd1 int, fd2 int) int {
2323
// Pipe represents a bidirectional communication channel
2424
@[noinit]
2525
pub struct Pipe {
26-
mut:
26+
pub mut:
2727
read_fd int = -1
2828
write_fd int = -1
2929
}
@@ -77,6 +77,15 @@ pub fn (p &Pipe) write(buffer []u8) !int {
7777
return result
7878
}
7979

80+
// write_string writes data from the string to the pipe
81+
pub fn (p &Pipe) write_string(s string) !int {
82+
result := C.write(p.write_fd, voidptr(s.str), s.len)
83+
if result == -1 {
84+
return error('Write failed')
85+
}
86+
return result
87+
}
88+
8089
// slurp reads all data from the pipe until EOF
8190
pub fn (mut p Pipe) slurp() []string {
8291
// Close write end to send EOF signal to the pipe

‎vlib/term/ui/termios_nix_test.v‎

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,27 @@
11
module ui
22

3+
import os
4+
35
fn test_get_cursor_position_reads_valid_row_column_data() ! {
4-
mut pipeset := [0, 0]
56
mut original_stdin_fd := -1
67
unsafe {
7-
if C.pipe(&pipeset[0]) == -1 {
8-
return error('unable to create pipe: ${C.strerror(C.errno)}')
9-
}
8+
mut pipe := os.pipe()!
109

1110
fake_cursor_pos_data := '\033[45;70R'
12-
written_bytes := C.write(pipeset[1], fake_cursor_pos_data.str, fake_cursor_pos_data.len)
11+
written_bytes := pipe.write_string(fake_cursor_pos_data)!
1312
if written_bytes == -1 {
14-
C.close(pipeset[0])
15-
C.close(pipeset[1])
13+
pipe.close()
1614
return error('error writing into pipe: ${C.strerror(C.errno)}')
1715
}
1816

19-
C.close(pipeset[1])
17+
C.close(pipe.write_fd)
2018

21-
if C.dup2(pipeset[0], C.STDIN_FILENO) == -1 {
22-
C.close(pipeset[0])
19+
if C.dup2(pipe.read_fd, C.STDIN_FILENO) == -1 {
20+
C.close(pipe.read_fd)
2321
return error('error redirecting stdin with dup2: ${C.strerror(C.errno)}')
2422
}
2523

26-
C.close(pipeset[0])
24+
C.close(pipe.read_fd)
2725

2826
cursor_pos_x, cursor_pos_y := get_cursor_position()
2927
assert cursor_pos_x == 45
@@ -32,29 +30,25 @@ fn test_get_cursor_position_reads_valid_row_column_data() ! {
3230
}
3331

3432
fn test_get_cursor_position_reads_empty_position_data() ! {
35-
mut pipeset := [0, 0]
3633
mut original_stdin_fd := -1
3734
unsafe {
38-
if C.pipe(&pipeset[0]) == -1 {
39-
return error('unable to create pipe: ${C.strerror(C.errno)}')
40-
}
35+
mut pipe := os.pipe()!
4136

4237
fake_cursor_pos_data := ''
43-
written_bytes := C.write(pipeset[1], fake_cursor_pos_data.str, fake_cursor_pos_data.len)
38+
written_bytes := pipe.write_string(fake_cursor_pos_data)!
4439
if written_bytes == -1 {
45-
C.close(pipeset[0])
46-
C.close(pipeset[1])
40+
pipe.close()
4741
return error('error writing into pipe: ${C.strerror(C.errno)}')
4842
}
4943

50-
C.close(pipeset[1])
44+
C.close(pipe.write_fd)
5145

52-
if C.dup2(pipeset[0], C.STDIN_FILENO) == -1 {
53-
C.close(pipeset[0])
46+
if C.dup2(pipe.read_fd, C.STDIN_FILENO) == -1 {
47+
C.close(pipe.read_fd)
5448
return error('error redirecting stdin with dup2: ${C.strerror(C.errno)}')
5549
}
5650

57-
C.close(pipeset[0])
51+
C.close(pipe.read_fd)
5852

5953
cursor_pos_x, cursor_pos_y := get_cursor_position()
6054
assert cursor_pos_x == -1

0 commit comments

Comments
 (0)