Rev 6926 | Rev 6928 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 6926 | Rev 6927 | ||
---|---|---|---|
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
2 | ;; ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2017. All rights reserved. ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2017. All rights reserved. ;; |
4 | ;; Distributed under terms of the GNU General Public License. ;; |
4 | ;; Distributed under terms of the GNU General Public License. ;; |
5 | ;; ;; |
5 | ;; ;; |
6 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
6 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
7 | 7 | ||
8 | $Revision: 6917 $ |
8 | $Revision: 6917 $ |
9 | 9 | ||
10 | O_CLOEXEC equ 0x40000 |
10 | O_CLOEXEC equ 0x40000 |
11 | PIPE_BUFFER_SIZE equ 4096 |
11 | PIPE_BUFFER_SIZE equ 4096 |
12 | 12 | ||
13 | 13 | ||
14 | iglobal |
14 | iglobal |
15 | align 4 |
15 | align 4 |
16 | pipe_file_ops: |
16 | pipe_file_ops: |
17 | dd pipe_close ;0 |
17 | dd pipe_close ;0 |
18 | dd pipe_read ;1 |
18 | dd pipe_read ;1 |
19 | dd pipe_write ;2 |
19 | dd pipe_write ;2 |
20 | endg |
20 | endg |
21 | 21 | ||
22 | ;int pipe2(int pipefd[2], int flags); |
22 | ;int pipe2(int pipefd[2], int flags); |
23 | ;ecx pipefd |
23 | ;ecx pipefd |
24 | ;edx flags |
24 | ;edx flags |
25 | 25 | ||
26 | align 4 |
26 | align 4 |
27 | sys_pipe2: |
27 | sys_pipe2: |
28 | .pipeflags equ esp+16 |
28 | .pipeflags equ esp+16 |
29 | .pipefd equ esp+12 |
29 | .pipefd equ esp+12 |
30 | .fdread equ esp+8 |
30 | .fdread equ esp+8 |
31 | .fdwrite equ esp+4 |
31 | .fdwrite equ esp+4 |
32 | .intpipe equ esp |
32 | .intpipe equ esp |
33 | 33 | ||
34 | push ebp |
34 | push ebp |
35 | test ecx, ecx |
35 | test ecx, ecx |
36 | mov ebp, -EFAULT |
36 | mov ebp, -EFAULT |
37 | js .fail |
37 | js .fail |
38 | 38 | ||
39 | test edx, not O_CLOEXEC |
39 | test edx, not O_CLOEXEC |
40 | mov ebp, -EINVAL |
40 | mov ebp, -EINVAL |
41 | jnz .fail |
41 | jnz .fail |
42 | 42 | ||
43 | push ecx |
43 | push ecx |
44 | push edx |
44 | push edx |
45 | sub esp, (5-2)*4 |
45 | sub esp, (5-2)*4 |
46 | 46 | ||
47 | mov ecx, sizeof.FILED |
47 | mov ecx, sizeof.FILED |
48 | call create_object |
48 | call create_object |
49 | mov [.fdread], eax |
49 | mov [.fdread], eax |
50 | test eax, eax |
50 | test eax, eax |
51 | mov ebp, -EMFILE |
51 | mov ebp, -EMFILE |
52 | jz .err_0 |
52 | jz .err_0 |
53 | 53 | ||
54 | mov ecx, sizeof.FILED |
54 | mov ecx, sizeof.FILED |
55 | call create_object |
55 | call create_object |
56 | mov [.fdwrite], eax |
56 | mov [.fdwrite], eax |
57 | test eax, eax |
57 | test eax, eax |
58 | jz .err_1 |
58 | jz .err_1 |
59 | 59 | ||
60 | mov eax, sizeof.PIPE |
60 | mov eax, sizeof.PIPE |
61 | call malloc |
61 | call malloc |
62 | test eax, eax |
62 | test eax, eax |
63 | mov ebp, -ENFILE |
63 | mov ebp, -ENFILE |
64 | jz .err_2 |
64 | jz .err_2 |
65 | 65 | ||
66 | mov ebp, eax |
66 | mov ebp, eax |
67 | 67 | ||
68 | stdcall create_ring_buffer, PIPE_BUFFER_SIZE, PG_SWR |
68 | stdcall create_ring_buffer, PIPE_BUFFER_SIZE, PG_SWR |
69 | test eax, eax |
69 | test eax, eax |
70 | jz .err_3 |
70 | jz .err_3 |
71 | 71 | ||
72 | mov [ebp+PIPE.pipe_ops], pipe_file_ops |
72 | mov [ebp+PIPE.pipe_ops], pipe_file_ops |
73 | mov [ebp+PIPE.buffer], eax |
73 | mov [ebp+PIPE.buffer], eax |
74 | 74 | ||
75 | xor eax, eax |
75 | xor eax, eax |
76 | mov [ebp+PIPE.count], eax |
76 | mov [ebp+PIPE.count], eax |
77 | mov [ebp+PIPE.read_end], eax |
77 | mov [ebp+PIPE.read_end], eax |
78 | mov [ebp+PIPE.write_end], eax |
78 | mov [ebp+PIPE.write_end], eax |
79 | 79 | ||
80 | inc eax |
80 | inc eax |
81 | mov [ebp+PIPE.readers], eax |
81 | mov [ebp+PIPE.readers], eax |
82 | mov [ebp+PIPE.writers], eax |
82 | mov [ebp+PIPE.writers], eax |
83 | 83 | ||
84 | lea ecx, [ebp+PIPE.pipe_lock] |
84 | lea ecx, [ebp+PIPE.pipe_lock] |
85 | call mutex_init |
85 | call mutex_init |
86 | 86 | ||
87 | lea ecx, [ebp+PIPE.rlist] |
87 | lea ecx, [ebp+PIPE.rlist] |
88 | list_init ecx |
88 | list_init ecx |
89 | 89 | ||
90 | lea ecx, [ebp+PIPE.wlist] |
90 | lea ecx, [ebp+PIPE.wlist] |
91 | list_init ecx |
91 | list_init ecx |
92 | 92 | ||
93 | mov eax, [.fdread] |
93 | mov eax, [.fdread] |
94 | mov edx, [.fdwrite] |
94 | mov edx, [.fdwrite] |
95 | mov ecx, [.pipefd] |
95 | mov ecx, [.pipefd] |
96 | 96 | ||
97 | mov [eax+FILED.magic], 'PIPE' |
97 | mov [eax+FILED.magic], 'PIPE' |
98 | mov [eax+FILED.destroy], 0 |
98 | mov [eax+FILED.destroy], 0 |
99 | mov [eax+FILED.file], ebp |
99 | mov [eax+FILED.file], ebp |
100 | 100 | ||
101 | mov [edx+FILED.magic], 'PIPE' |
101 | mov [edx+FILED.magic], 'PIPE' |
102 | mov [edx+FILED.destroy], 0 |
102 | mov [edx+FILED.destroy], 0 |
103 | mov [edx+FILED.file], ebp |
103 | mov [edx+FILED.file], ebp |
104 | 104 | ||
105 | mov [ecx], eax |
105 | mov [ecx], eax |
106 | mov [ecx+4], edx |
106 | mov [ecx+4], edx |
107 | add esp, 5*4 |
107 | add esp, 5*4 |
108 | pop ebp |
108 | pop ebp |
109 | xor eax, eax |
109 | xor eax, eax |
110 | mov [esp+SYSCALL_STACK._eax], eax |
110 | mov [esp+SYSCALL_STACK._eax], eax |
111 | ret |
111 | ret |
112 | .err_3: |
112 | .err_3: |
113 | mov eax, ebp |
113 | mov eax, ebp |
114 | call free |
114 | call free |
115 | mov ebp, -ENFILE |
115 | mov ebp, -ENFILE |
116 | .err_2: |
116 | .err_2: |
117 | mov ecx, [.fdwrite] |
117 | mov ecx, [.fdwrite] |
118 | call destroy_object |
118 | call destroy_object |
119 | .err_1: |
119 | .err_1: |
120 | mov ecx, [.fdread] |
120 | mov ecx, [.fdread] |
121 | call destroy_object |
121 | call destroy_object |
122 | .err_0: |
122 | .err_0: |
123 | add esp, 5*4 |
123 | add esp, 5*4 |
124 | .fail: |
124 | .fail: |
125 | mov [esp+SYSCALL_STACK._eax], ebp |
125 | mov [esp+SYSCALL_STACK._eax], ebp |
126 | pop ebp |
126 | pop ebp |
127 | ret |
127 | ret |
128 | 128 | ||
129 | purge .pipeflags |
129 | purge .pipeflags |
130 | purge .filefd |
130 | purge .filefd |
131 | purge .fdread |
131 | purge .fdread |
132 | purge .fdwrite |
132 | purge .fdwrite |
133 | purge .intpipe |
133 | purge .intpipe |
134 | 134 | ||
135 | 135 | ||
136 | ; edx buf |
136 | ; edx buf |
137 | ; esi count |
137 | ; esi count |
138 | ; ebp pipe |
138 | ; ebp pipe |
139 | 139 | ||
140 | align 4 |
140 | align 4 |
141 | pipe_read: |
141 | pipe_read: |
142 | mov edi, edx |
142 | mov edi, edx |
- | 143 | ||
- | 144 | .again: |
|
143 | lea ecx, [ebp+PIPE.pipe_lock] |
145 | lea ecx, [ebp+PIPE.pipe_lock] |
144 | call mutex_lock |
146 | call mutex_lock |
145 | 147 | ||
146 | xor eax, eax |
148 | xor eax, eax |
147 | cmp eax, [ebp+PIPE.writers] |
149 | cmp eax, [ebp+PIPE.writers] |
148 | je .eof |
150 | je .eof |
149 | 151 | ||
150 | mov ecx, [ebp+PIPE.count] |
152 | mov ecx, [ebp+PIPE.count] |
151 | test ecx, ecx |
153 | test ecx, ecx |
152 | jz .wait |
154 | jz .wait |
153 | 155 | ||
154 | .check_count: |
156 | .check_count: |
155 | cmp ecx, esi |
157 | cmp ecx, esi |
156 | jb .read |
158 | jb .read |
157 | mov ecx, esi |
159 | mov ecx, esi |
158 | .read: |
160 | .read: |
159 | mov esi, [ebp+PIPE.buffer] |
161 | mov esi, [ebp+PIPE.buffer] |
160 | add esi, [ebp+PIPE.read_end] |
162 | add esi, [ebp+PIPE.read_end] |
161 | mov [esp+SYSCALL_STACK._eax], ecx |
163 | mov [esp+SYSCALL_STACK._eax], ecx |
162 | sub [ebp+PIPE.count], ecx |
164 | sub [ebp+PIPE.count], ecx |
163 | cld |
165 | cld |
164 | rep stosb |
166 | rep movsb |
165 | and esi, 0xFFF |
167 | and esi, 0xFFF |
166 | add [ebp+PIPE.read_end], esi |
168 | mov [ebp+PIPE.read_end], esi |
167 | 169 | ||
168 | lea ecx, [ebp+PIPE.pipe_lock] |
170 | lea ecx, [ebp+PIPE.pipe_lock] |
169 | call mutex_unlock |
171 | call mutex_unlock |
170 | ret |
172 | ret |
171 | 173 | ||
172 | .wait: |
174 | .wait: |
173 | - | ||
174 | sub esp, sizeof.MUTEX_WAITER |
175 | sub esp, sizeof.MUTEX_WAITER |
175 | mov ebx, [TASK_BASE] |
176 | mov ebx, [TASK_BASE] |
176 | mov [esp+MUTEX_WAITER.task], ebx |
177 | mov [esp+MUTEX_WAITER.task], ebx |
177 | lea edx, [ebp+PIPE.rlist] |
178 | lea edx, [ebp+PIPE.rlist] |
178 | 179 | ||
179 | list_add_tail esp, edx ;esp= new waiter, edx= list head |
180 | list_add_tail esp, edx ;esp= new waiter, edx= list head |
180 | - | ||
181 | .again: |
181 | |
182 | lea ecx, [ebp+PIPE.pipe_lock] |
182 | lea ecx, [ebp+PIPE.pipe_lock] |
183 | call mutex_unlock |
183 | call mutex_unlock |
184 | 184 | ||
185 | mov [ebx+TASKDATA.state], 1 |
185 | mov [ebx+TASKDATA.state], 1 |
186 | call change_task |
186 | call change_task |
- | 187 | ||
- | 188 | list_del esp |
|
- | 189 | add esp, sizeof.MUTEX_WAITER |
|
- | 190 | jmp .again |
|
- | 191 | ||
- | 192 | .eof: |
|
- | 193 | mov [esp+SYSCALL_STACK._eax], eax |
|
- | 194 | lea ecx, [ebp+PIPE.pipe_lock] |
|
- | 195 | call mutex_unlock |
|
- | 196 | ret |
|
- | 197 | ||
- | 198 | ; edx buf |
|
- | 199 | ; esi count |
|
- | 200 | ; ebp pipe |
|
- | 201 | ||
- | 202 | align 4 |
|
- | 203 | pipe_write: |
|
- | 204 | mov edi, edx |
|
- | 205 | ||
187 | 206 | .again: |
|
188 | lea ecx, [ebp+PIPE.pipe_lock] |
207 | lea ecx, [ebp+PIPE.pipe_lock] |
189 | call mutex_lock |
208 | call mutex_lock |
- | 209 | ||
- | 210 | xor eax, eax |
|
- | 211 | cmp eax, [ebp+PIPE.readers] |
|
- | 212 | je .epipe |
|
190 | 213 | ||
191 | mov ecx, [ebp+PIPE.count] |
214 | mov ecx, [ebp+PIPE.count] |
192 | test ecx, ecx |
215 | sub ecx, 4096 |
- | 216 | jz .wait |
|
- | 217 | ||
- | 218 | .check_count: |
|
- | 219 | cmp ecx, esi |
|
- | 220 | jb .write |
|
- | 221 | mov ecx, esi |
|
- | 222 | .write: |
|
- | 223 | mov esi, [ebp+PIPE.buffer] |
|
- | 224 | add esi, [ebp+PIPE.write_end] |
|
- | 225 | mov [esp+SYSCALL_STACK._eax], ecx |
|
- | 226 | add [ebp+PIPE.count], ecx |
|
- | 227 | cld |
|
- | 228 | rep movsb |
|
- | 229 | and esi, 0xFFF |
|
- | 230 | mov [ebp+PIPE.write_end], esi |
|
- | 231 | ||
- | 232 | lea ecx, [ebp+PIPE.pipe_lock] |
|
- | 233 | call mutex_unlock |
|
- | 234 | ret |
|
- | 235 | ||
- | 236 | .wait: |
|
- | 237 | sub esp, sizeof.MUTEX_WAITER |
|
- | 238 | mov ebx, [TASK_BASE] |
|
- | 239 | mov [esp+MUTEX_WAITER.task], ebx |
|
- | 240 | lea edx, [ebp+PIPE.wlist] |
|
- | 241 | ||
- | 242 | list_add_tail esp, edx ;esp= new waiter, edx= list head |
|
- | 243 | ||
- | 244 | lea ecx, [ebp+PIPE.pipe_lock] |
|
- | 245 | call mutex_unlock |
|
- | 246 | ||
- | 247 | mov [ebx+TASKDATA.state], 1 |
|
193 | jz .again |
248 | call change_task |
194 | 249 | ||
195 | list_del esp |
250 | list_del esp |
196 | add esp, sizeof.MUTEX_WAITER |
251 | add esp, sizeof.MUTEX_WAITER |
197 | jmp .check_count |
252 | jmp .again |
198 | 253 | ||
199 | .eof: |
254 | .epipe: |
200 | mov [esp+SYSCALL_STACK._eax], eax |
255 | mov [esp+SYSCALL_STACK._eax], -EPIPE |
201 | lea ecx, [ebp+PIPE.pipe_lock] |
256 | lea ecx, [ebp+PIPE.pipe_lock] |
202 | call mutex_unlock |
257 | call mutex_unlock |
203 | ret |
258 | ret |
204 | - | ||
205 | 259 | ||
206 | align 4 |
260 | align 4 |
207 | pipe_close: |
- | |
208 | pipe_write: |
261 | pipe_close: |
209 | mov [esp+SYSCALL_STACK._eax], -EBADF |
262 | mov [esp+SYSCALL_STACK._eax], -EBADF |
210 | ret |
263 | ret |