Skip to content

Commit 54c5764

Browse files
author
HBuczynski
committed
posix: add unnamed pipes
RTOS-299
1 parent c47aaf1 commit 54c5764

File tree

6 files changed

+257
-9
lines changed

6 files changed

+257
-9
lines changed

posix/Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@
55
# Author: Pawel Pisarczyk
66
#
77

8-
OBJS += $(addprefix $(PREFIX_O)posix/, posix.o inet.o unix.o fdpass.o)
8+
OBJS += $(addprefix $(PREFIX_O)posix/, posix.o inet.o unix.o fdpass.o pipe.o)
99

posix/pipe.c

+207
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
/*
2+
* Phoenix-RTOS
3+
*
4+
* Operating system kernel
5+
*
6+
* Unnamed pipes
7+
*
8+
* Copyright 2022 Phoenix Systems
9+
* Author: Hubert Buczynski
10+
*
11+
* This file is part of Phoenix-RTOS.
12+
*
13+
* %LICENSE%
14+
*/
15+
16+
#include "pipe.h"
17+
18+
#include "../usrv.h"
19+
#include "../lib/cbuffer.h"
20+
#include "../include/posix.h"
21+
22+
23+
#define SIZE_PIPE_BUFF (4 * SIZE_PAGE)
24+
25+
typedef struct {
26+
rbnode_t linkage;
27+
oid_t oid;
28+
29+
lock_t lock;
30+
void *data;
31+
cbuffer_t cbuff;
32+
} pipe_t;
33+
34+
35+
static struct {
36+
rbtree_t pipes;
37+
unsigned int cnt;
38+
lock_t lock;
39+
} pipe_common;
40+
41+
42+
static int pipe_cmp(rbnode_t *n1, rbnode_t *n2)
43+
{
44+
pipe_t *p1 = lib_treeof(pipe_t, linkage, n1);
45+
pipe_t *p2 = lib_treeof(pipe_t, linkage, n2);
46+
int res;
47+
48+
if (p1->oid.id < p2->oid.id) {
49+
res = -1;
50+
}
51+
else if (p1->oid.id > p2->oid.id) {
52+
res = 1;
53+
}
54+
else {
55+
res = 0;
56+
}
57+
58+
return res;
59+
}
60+
61+
62+
static pipe_t *pipe_getPipe(const oid_t *oid)
63+
{
64+
pipe_t p;
65+
p.oid = *oid;
66+
67+
return lib_treeof(pipe_t, linkage, lib_rbFind(&pipe_common.pipes, &p.linkage));
68+
}
69+
70+
71+
static int pipe_destroy(oid_t oid)
72+
{
73+
pipe_t *pipe = pipe_getPipe(&oid);
74+
if (pipe == NULL) {
75+
return -EINVAL;
76+
}
77+
78+
proc_lockSet(&pipe_common.lock);
79+
lib_rbRemove(&pipe_common.pipes, &pipe->linkage);
80+
proc_lockClear(&pipe_common.lock);
81+
82+
proc_lockSet(&pipe->lock);
83+
_cbuffer_free(&pipe->cbuff);
84+
vm_kfree(pipe->data);
85+
proc_lockClear(&pipe->lock);
86+
87+
proc_lockDone(&pipe->lock);
88+
vm_kfree(pipe);
89+
90+
return EOK;
91+
}
92+
93+
94+
static int pipe_create(oid_t *oid)
95+
{
96+
int res;
97+
pipe_t *p;
98+
99+
p = vm_kmalloc(sizeof(pipe_t));
100+
if (p == NULL) {
101+
return -ENOMEM;
102+
}
103+
104+
p->data = vm_kmalloc(SIZE_PIPE_BUFF);
105+
if (p->data == NULL) {
106+
vm_kfree(p);
107+
return -ENOMEM;
108+
}
109+
110+
res = proc_lockInit(&p->lock);
111+
if (res < 0) {
112+
vm_kfree(p->data);
113+
vm_kfree(p);
114+
return res;
115+
}
116+
117+
res = _cbuffer_init(&p->cbuff, p->data, SIZE_PIPE_BUFF);
118+
if (res < 0) {
119+
proc_lockClear(&p->lock);
120+
vm_kfree(p->data);
121+
vm_kfree(p);
122+
return res;
123+
}
124+
125+
p->oid.port = USRV_PORT;
126+
p->oid.id = (id_t)(++pipe_common.cnt << USRV_ID_BITS) | USRV_ID_PIPES;
127+
128+
proc_lockSet(&pipe_common.lock);
129+
lib_rbInsert(&pipe_common.pipes, &p->linkage);
130+
proc_lockClear(&pipe_common.lock);
131+
132+
return EOK;
133+
}
134+
135+
136+
static int pipe_read(const oid_t *oid, void *buf, size_t sz, unsigned mode)
137+
{
138+
pipe_t *pipe = pipe_getPipe(oid);
139+
140+
if (pipe == NULL) {
141+
return -EINVAL;
142+
}
143+
144+
145+
return 0;
146+
}
147+
148+
149+
static int pipe_write(const oid_t *oid, const void *buf, size_t sz, unsigned mode)
150+
{
151+
pipe_t *pipe = pipe_getPipe(oid);
152+
153+
if (pipe == NULL) {
154+
return -EINVAL;
155+
}
156+
157+
158+
if (mode & O_NONBLOCK) {
159+
160+
}
161+
162+
return 0;
163+
}
164+
165+
166+
void pipe_msgHandler(msg_t *msg, oid_t oid, unsigned long int rid)
167+
{
168+
switch (msg->type) {
169+
case mtOpen:
170+
/* TODO: increase refs in pipes */
171+
break;
172+
173+
case mtCreate:
174+
msg->o.create.err = pipe_create(&msg->o.create.oid);
175+
break;
176+
177+
case mtRead:
178+
msg->o.io.err = pipe_read(&msg->i.io.oid, msg->o.data, msg->o.size, msg->i.io.mode);
179+
break;
180+
181+
case mtWrite:
182+
msg->o.io.err = pipe_write(&msg->i.io.oid, msg->i.data, msg->i.size, msg->i.io.mode);
183+
break;
184+
185+
case mtClose:
186+
/* TODO: manage refs ine pipes and destroy pipe */
187+
break;
188+
189+
case mtDevCtl:
190+
/* TODO: handle fcntl */
191+
break;
192+
193+
default:
194+
break;
195+
}
196+
197+
proc_respond(oid.port, msg, rid);
198+
}
199+
200+
201+
void pipe_init(void)
202+
{
203+
pipe_common.cnt = 0;
204+
205+
proc_lockInit(&pipe_common.lock);
206+
lib_rbInit(&pipe_common.pipes, pipe_cmp, NULL);
207+
}

posix/pipe.h

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Phoenix-RTOS
3+
*
4+
* Operating system kernel
5+
*
6+
* Unnamed pipes
7+
*
8+
* Copyright 2022 Phoenix Systems
9+
* Author: Hubert Buczynski
10+
*
11+
* This file is part of Phoenix-RTOS.
12+
*
13+
* %LICENSE%
14+
*/
15+
16+
#ifndef _POSIX_PIPE_H_
17+
#define _POSIX_PIPE_H_
18+
19+
#include "../proc/msg.h"
20+
21+
22+
extern void pipe_msgHandler(msg_t *msg, oid_t oid, unsigned long int rid);
23+
24+
25+
extern void pipe_init(void);
26+
27+
28+
#endif

posix/posix.c

+14-4
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@
2020
#include "../proc/proc.h"
2121

2222
#include "posix.h"
23+
#include "pipe.h"
2324
#include "posix_private.h"
2425
#include "../lib/cbuffer.h"
26+
#include "../usrv.h"
2527

2628
#ifdef CPU_STM32
2729
#define MAX_FD_COUNT 8
@@ -795,12 +797,19 @@ int posix_pipe(int fildes[2])
795797

796798
hal_memset(&oid, 0, sizeof(oid));
797799

798-
if ((res = proc_lookup("/dev/posix/pipes", NULL, &pipesrv)) < 0) {
799-
pinfo_put(p);
800-
return res == -EINTR ? res : -ENOSYS;
800+
res = proc_lookup("/dev/posix/pipes", NULL, &pipesrv);
801+
if (res < 0) {
802+
/* Use anonymous pipe from kernel */
803+
pipesrv.port = USRV_PORT;
804+
pipesrv.id = USRV_ID_PIPES;
805+
806+
}
807+
else {
808+
/* Use anonymous pipes from external server */
801809
}
802810

803-
if ((res = proc_create(pipesrv.port, pxBufferedPipe, O_RDONLY | O_WRONLY, oid, pipesrv, NULL, &oid)) < 0) {
811+
res = proc_create(pipesrv.port, pxBufferedPipe, O_RDONLY | O_WRONLY, oid, pipesrv, NULL, &oid);
812+
if (res < 0) {
804813
pinfo_put(p);
805814
return res;
806815
}
@@ -833,6 +842,7 @@ int posix_pipe(int fildes[2])
833842
vm_kfree(fi);
834843

835844
pinfo_put(p);
845+
/* FIXME: destroy pipe */
836846
return -EMFILE;
837847
}
838848

usrv.c

+1-4
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,6 @@
2424
#include "proc/ports.h"
2525

2626

27-
#define USRV_ID_LOG 0
28-
29-
3027
static struct {
3128
oid_t oid;
3229
} usrv_common;
@@ -92,7 +89,7 @@ static void usrv_msgthr(void *arg)
9289
continue;
9390
}
9491

95-
switch (oid.id) {
92+
switch (oid.id & 0xf) {
9693
case USRV_ID_LOG:
9794
log_msgHandler(&msg, oid, rid);
9895
break;

usrv.h

+6
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@
1616
#ifndef _USRV_H_
1717
#define _USRV_H_
1818

19+
#define USRV_PORT 0
20+
#define USRV_ID_LOG 0
21+
#define USRV_ID_PIPES 1
22+
23+
/* LSB number for unit identifier in oid.id */
24+
#define USRV_ID_BITS 4
1925

2026
extern void _usrv_init(void);
2127

0 commit comments

Comments
 (0)