1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00
RIOT/cpu/native/syscalls.c

155 lines
3.1 KiB
C
Raw Normal View History

/**
* Native CPU syscall managing
*
* Wrap system calls and system call invoking library calls to make
* sure no context switches happen during a system call.
*
* Copyright (C) 2013 Ludwig Ortmann
*
* This file subject to the terms and conditions of the GNU Lesser General
* Public License. See the file LICENSE in the top level directory for more
* details.
*
* @ingroup native_cpu
* @{
* @file
* @author Ludwig Ortmann <ludwig.ortmann@fu-berlin.de>
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#include <dlfcn.h>
#else
#include <dlfcn.h>
#endif
#include <err.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include "cpu.h"
#include "native_internal.h"
#define ENABLE_DEBUG (0)
#include "debug.h"
extern volatile tcb_t *active_thread;
ssize_t (*real_read)(int fd, void *buf, size_t count);
ssize_t (*real_write)(int fd, const void *buf, size_t count);
void _native_syscall_enter()
{
_native_in_syscall++;
DEBUG("> _native_in_syscall: %d\n", _native_in_syscall);
}
void _native_syscall_leave()
{
_native_in_syscall--;
DEBUG("< _native_in_syscall: %d\n", _native_in_syscall);
if ((_native_sigpend > 0) && (_native_in_isr == 0) && (_native_in_syscall == 0)) {
_native_in_isr = 1;
_native_cur_ctx = (ucontext_t *)active_thread->sp;
makecontext(&native_isr_context, native_irq_handler, 0);
swapcontext(_native_cur_ctx, &native_isr_context);
}
}
ssize_t read(int fd, void *buf, size_t count)
{
ssize_t r;
_native_syscall_enter();
r = real_read(fd, buf, count);
_native_syscall_leave();
return r;
}
ssize_t write(int fd, const void *buf, size_t count)
{
ssize_t r;
_native_syscall_enter();
//real_write(fd, "real_write: ", 12);
r = real_write(fd, buf, count);
_native_syscall_leave();
return r;
}
int putchar(int c) {
write(STDOUT_FILENO, &c, 1);
return 0;
}
int puts(const char *s)
{
int r;
r = write(STDOUT_FILENO, (char*)s, strlen(s));
putchar('\n');
return r;
}
char *make_message(const char *format, va_list argp)
{
int n;
int size = 100;
char *message, *temp;
if ((message = malloc(size)) == NULL)
return NULL;
while (1) {
n = vsnprintf(message, size, format, argp);
if (n < 0)
return NULL;
if (n < size)
return message;
size = n + 1;
if ((temp = realloc(message, size)) == NULL) {
free(message);
return NULL;
} else {
message = temp;
}
}
}
int printf(const char *format, ...)
{
int r;
va_list argp;
char *m;
va_start(argp, format);
if ((m = make_message(format, argp)) == NULL) {
err(EXIT_FAILURE, "malloc");
}
r = write(STDOUT_FILENO, m, strlen(m));
va_end(argp);
free(m);
return r;
}
int vprintf(const char *format, va_list argp)
{
int r;
char *m;
if ((m = make_message(format, argp)) == NULL) {
err(EXIT_FAILURE, "malloc");
}
r = write(STDOUT_FILENO, m, strlen(m));
free(m);
return r;
}