Luna/libc/src/stdio.cpp

166 lines
3.3 KiB
C++
Raw Normal View History

#define _LUNA_SYSTEM_ERROR_EXTENSIONS
#include <bits/errno-return.h>
#include <fcntl.h>
#include <luna/Format.h>
#include <stdio.h>
#include <stdlib.h>
2023-01-07 00:49:26 +00:00
#include <string.h>
#include <sys/syscall.h>
#include <unistd.h>
FILE* stderr = nullptr;
extern "C"
{
2023-01-07 00:49:26 +00:00
int console_write(const char* str, size_t size)
{
2023-01-07 00:49:26 +00:00
long rc = syscall(SYS_console_write, str, size);
__errno_return(rc, int);
}
FILE* fopen(const char* path, const char*)
{
// FIXME: Parse the mode string.
int fd = open(path, 0);
if (fd < 0) return nullptr;
FILE* f = (FILE*)malloc(sizeof(FILE));
if (!f)
{
close(fd);
return nullptr;
}
f->_fd = fd;
clearerr(f);
return f;
}
int fclose(FILE* stream)
{
if (close(stream->_fd) < 0) return EOF;
free(stream);
return 0;
}
size_t fread(void* buf, size_t size, size_t nmemb, FILE* stream)
{
if (size * nmemb == 0) return 0;
ssize_t nread = read(stream->_fd, buf, size * nmemb);
if (nread < 0)
{
stream->_err = 1;
return 0;
}
else if (nread == 0)
{
stream->_eof = 1;
return 0;
}
else
return (size_t)nread / size;
}
int ferror(FILE* stream)
{
return stream->_err;
}
int feof(FILE* stream)
{
return stream->_eof;
}
void clearerr(FILE* stream)
{
stream->_eof = stream->_err = 0;
}
int vsnprintf(char* buf, size_t max, const char* format, va_list ap)
{
return (int)vstring_format(buf, max, format, ap);
}
int snprintf(char* buf, size_t max, const char* format, ...)
{
va_list ap;
va_start(ap, format);
int rc = vsnprintf(buf, max, format, ap);
va_end(ap);
return rc;
}
int vsprintf(char* buf, const char* format, va_list ap)
{
return vsnprintf(buf, (size_t)-1, format, ap);
}
int sprintf(char* buf, const char* format, ...)
{
va_list ap;
va_start(ap, format);
int rc = vsnprintf(buf, (size_t)-1, format, ap);
va_end(ap);
return rc;
}
2023-01-07 00:49:26 +00:00
int printf(const char* format, ...)
{
va_list ap;
va_start(ap, format);
int rc = (int)cstyle_format(
format,
[](char c, void*) -> Result<void> {
console_write(&c, 1);
return {};
},
nullptr, ap)
.value();
2023-01-07 00:49:26 +00:00
va_end(ap);
return rc;
}
int puts(const char* s)
{
if (console_write(s, strlen(s)) < 0) return -1;
if (console_write("\n", 1) < 0) return -1;
return 0;
}
2023-01-13 20:08:10 +00:00
void perror(const char* s)
{
// FIXME: Output to stderr when available.
int err = errno;
if (s && *s) printf("%s: ", s);
printf("%s\n", strerror(err));
}
}
void debug_log_impl(const char* format, va_list ap)
{
cstyle_format(
format,
[](char c, void*) -> Result<void> {
console_write(&c, 1);
return {};
},
nullptr, ap)
.value();
console_write("\n", 1);
}