forked from ROMEO/fsw-ws
working on threadsafe syscalls
This commit is contained in:
@@ -7,6 +7,10 @@
|
||||
#include "interface_fds.h"
|
||||
#include "uart.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <reent.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int compare_string_chars(const char *c_string, const char *chars,
|
||||
size_t chars_len) {
|
||||
for(int i = 0; i < chars_len; i++) {
|
||||
@@ -39,6 +43,8 @@ ssize_t hw_device_transfer(int fd, void *sendbuffer, void *receivebuffer,
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// TODO move into uart.c
|
||||
// we could implement interrupt based nonblocking sending using a queue
|
||||
// like we do receiving (where we need it for the small hw buffer)
|
||||
// but in the end, we do not want too many interrupts, so we do it blocking
|
||||
@@ -59,6 +65,7 @@ int hw_interface_write(int fd, const char *ptr, int len) {
|
||||
uart_send(XPS_UART1_BASEADDR, ptr, len);
|
||||
return len;
|
||||
}
|
||||
_REENT_ERRNO(_REENT) = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
+22
-14
@@ -4,31 +4,39 @@
|
||||
#include "../hardware/interface_access.h"
|
||||
#include "../hardware/interface_fds.h"
|
||||
|
||||
// newlib offers a (weak) write implementation which
|
||||
// is reentrant by calling _read_r which in turn
|
||||
// relies on _read which we implement here.
|
||||
// This way, we get a global, reentrant read implementation
|
||||
// NOTE: This might be architecture dependent, so check your
|
||||
// newlib implementation!
|
||||
int _read(int fd, char *ptr, int len) {
|
||||
#include <errno.h>
|
||||
#include <reent.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int read(int fd, void *ptr, size_t len) {
|
||||
if (ptr == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 0 is stdin, TODO: do we support it?
|
||||
if (fd < 1) {
|
||||
_REENT_ERRNO(_REENT) = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// 0 is stdin, TODO: do we support it?
|
||||
if (fd < 1) {
|
||||
_REENT_ERRNO(_REENT) = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// stdout and stderr
|
||||
if (fd < 3) {
|
||||
_REENT_ERRNO(_REENT) = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fd < INTERFACE_FDS_NEXT) {
|
||||
return hw_interface_read(fd, ptr, len);
|
||||
int result = hw_interface_read(fd, ptr, len);
|
||||
if (result >= 0) {
|
||||
return result;
|
||||
} else if (_REENT_ERRNO(_REENT) != EBADF) {
|
||||
return result;
|
||||
}
|
||||
// continue if fd did not match to try other fd providers
|
||||
}
|
||||
|
||||
// we do not have dynamic fds, so fd is invalid
|
||||
_REENT_ERRNO(_REENT) = EBADF;
|
||||
return -1;
|
||||
}
|
||||
+21
-13
@@ -4,39 +4,47 @@
|
||||
#include "../hardware/interface_access.h"
|
||||
#include "../hardware/interface_fds.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <reent.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// newlib offers a (weak) write implementation which
|
||||
// is reentrant by calling _write_r which in turn
|
||||
// relies on _write which we implement here.
|
||||
// This way, we get a global, reentrant write implementation
|
||||
// NOTE: This might be architecture dependent, so check your
|
||||
// newlib implementation!
|
||||
int _write(int fd, const char *ptr, int len) {
|
||||
int write(int fd, const void *ptr, size_t len) {
|
||||
if (ptr == NULL) {
|
||||
return 0;
|
||||
_REENT_ERRNO(_REENT) = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
//TODO check len
|
||||
|
||||
// 0 is stdin, do not write to it
|
||||
if (fd < 1) {
|
||||
return -1; // TODO error
|
||||
_REENT_ERRNO(_REENT) = EBADF;
|
||||
return -1;
|
||||
}
|
||||
// we only support a single debug UART, so
|
||||
// stdout and stderr are the same and go to the xilinx stdout UART
|
||||
// We output directely to avoid loops and allow debugging (not via a write)
|
||||
if (fd < 3) {
|
||||
int todo;
|
||||
size_t todo;
|
||||
|
||||
const char *data = ptr;
|
||||
|
||||
for (todo = 0; todo < len; todo++) {
|
||||
outbyte(*ptr++);
|
||||
outbyte(*data++);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
if (fd < INTERFACE_FDS_NEXT) {
|
||||
return hw_interface_write(fd, ptr, len);
|
||||
int result = hw_interface_write(fd, ptr, len);
|
||||
if (result >= 0) {
|
||||
return result;
|
||||
} else if (_REENT_ERRNO(_REENT) != EBADF) {
|
||||
return result;
|
||||
}
|
||||
// continue if fd did not match to try other fd providers
|
||||
}
|
||||
|
||||
// we do not have dynamic fds, so fd is invalid
|
||||
return -1;
|
||||
_REENT_ERRNO(_REENT) = EBADF;
|
||||
return -1;
|
||||
}
|
||||
Reference in New Issue
Block a user