#ifndef __CORAX_IPC_H
#define __CORAX_IPC_H
-struct cxmsg {
- u32_t cm_src;
- u32_t cm_dst;
- u32_t cm_len;
+#define CX_MSG_RETVAL 0
+#define CX_MSG_READ 1
+#define CX_MSG_WRITE 2
+#define CX_MSG_FLUSH 3
+
+struct cxmsg_data_stdio {
+ int sio_fd;
+ char sio_data[];
+};
- u32_t cm_type;
+struct cxmsg_hdr {
+ u32_t cxh_src;
+ u32_t cxh_dst;
+ u32_t cxh_len;
+ u32_t cxh_type;
+};
+
+struct cxmsg {
+ struct cxmsg_hdr cm_hdr;
union {
+ int CM_retval;
+ struct cxmsg_data_stdio CM_stdio;
u8_t CM_data[CONFIG_IPC_MSGSIZE];
} CM_dat;
};
-#define cm_data CM_dat.CM_data
+#define cm_src cm_hdr.cxh_src
+#define cm_dst cm_hdr.cxh_dst
+#define cm_len cm_hdr.cxh_len
+#define cm_type cm_hdr.cxh_type
+
+#define cm_stdio CM_dat.CM_stdio
+#define cm_retval CM_dat.CM_retval
+#define cm_data CM_dat.CM_data
#define PID_INIT 1
#define PID_NET 10
#include <config.h>
#include <crxstd.h>
#include <corax/errno.h>
+#include <stddef.h>
-extern int wait(int*);
+#define STDIN 0
+#define STDOUT 1
+#define STDERR 2
+
+static int stdio_read(int fd, char *dst, size_t dsize)
+{
+ return(-ENOSYS);
+}
+
+static int stdio_write(int fd, const char *src, const size_t slen)
+{
+ return(-ENOSYS);
+}
+
+static int stdio_flush(int fd)
+{
+ if(fd < STDIN) {
+ return(-EINVAL);
+ }
+
+ if(fd > STDERR) {
+ return(-EBADF);
+ }
+
+ return(0);
+}
void _stdio(void)
{
err = cxrecv(PID_ANY, &msg);
err = 0;
+ /*
+ * The `cm_len' member includes the number of bytes consumed by the header
+ * of the message, so we need to substract offsetof(struct cxmsg, cm_data)
+ * to get the number of bytes that are supposed to be in the payload.
+ */
+
+ if((msg.cm_len - offsetof(struct cxmsg, cm_stdio.sio_data)) > msg.cm_len) {
+ /* underflow - discard message */
+ continue;
+ }
+
+ msg.cm_len -= offsetof(struct cxmsg, cm_stdio.sio_data);
+
+ if(msg.cm_len > (sizeof(msg.cm_data) - offsetof(struct cxmsg, cm_stdio.sio_data))) {
+ /* message allegedly contains more data than possible - malicious input? */
+ continue;
+ }
+
+ /* msg.cm_len now contains the number of bytes in sio_data */
+
if(err > 0) {
- /* FIXME: Handle message */
+ switch(msg.cm_type) {
+ case CX_MSG_READ:
+ err = stdio_read(msg.cm_stdio.sio_fd,
+ msg.cm_stdio.sio_data,
+ msg.cm_len);
+ break;
+
+ case CX_MSG_WRITE:
+ err = stdio_write(msg.cm_stdio.sio_fd,
+ msg.cm_stdio.sio_data,
+ msg.cm_len);
+ break;
+
+ case CX_MSG_FLUSH:
+ err = stdio_flush(msg.cm_stdio.sio_fd);
+ break;
+
+ default:
+ /* malformed input? */
+ err = -EINVAL;
+ break;
+ }
msg.cm_dst = msg.cm_src;
- msg.cm_type = -ENOSYS;
+ msg.cm_type = CX_MSG_RETVAL;
+ msg.cm_retval = err;
+ msg.cm_len = sizeof(msg.cm_hdr) + sizeof(int);
+
cxsend(msg.cm_dst, &msg);
}
}