Compare commits

..

10 Commits

Author SHA1 Message Date
0ae409ae22
ports: Some enhancements in make-package.sh
Some checks failed
continuous-integration/drone/push Build is failing
2023-08-11 18:25:07 +02:00
181b4c151b
tools: Build libstdc++ 2023-08-11 18:24:38 +02:00
0c64b6e040
libc: Add some stub network-related header files 2023-08-11 18:09:45 +02:00
fb3c31907d
fix 2023-08-11 18:09:28 +02:00
52064e0317
libc+kernel: Add alarm() and getpagesize() 2023-08-11 18:09:12 +02:00
ec3c1132d2
libc: Fix constness of some socket functions 2023-08-11 18:00:15 +02:00
5ea73197ad
libluna: Add a bunch more errno definitions 2023-08-11 17:59:41 +02:00
5a1adcb2a6
libc: Add putenv 2023-08-11 17:59:04 +02:00
c4f6191e24
libc: Implement some simple stuff needed for gcc 2023-08-08 22:06:11 +02:00
39e4fbd112
libc: Provide a bunch of math functions wrapped around compiler builtins 2023-08-08 20:38:38 +02:00
32 changed files with 657 additions and 108 deletions

View File

@ -44,6 +44,7 @@ set(SOURCES
src/sys/signal.cpp
src/sys/socket.cpp
src/sys/poll.cpp
src/sys/alarm.cpp
src/fs/VFS.cpp
src/fs/Pipe.cpp
src/fs/Mount.cpp

15
kernel/src/sys/alarm.cpp Normal file
View File

@ -0,0 +1,15 @@
#include "sys/Syscall.h"
#include "thread/Scheduler.h"
Result<u64> sys_alarm(Registers*, SyscallArgs args)
{
unsigned int seconds = (unsigned int)args[0];
auto* current = Scheduler::current();
u64 time_left = current->alarm_ticks_left;
current->alarm_ticks_left = seconds * 1000;
return time_left * 1000;
}

View File

@ -282,6 +282,8 @@ namespace Scheduler
{
if (thread->sleep_ticks_left == 0 || --thread->sleep_ticks_left == 0) thread->wake_up();
}
if (thread->alarm_ticks_left && --thread->alarm_ticks_left == 0) thread->send_signal(SIGALRM);
}
if (!g_current->ticks_left) switch_task(regs);

View File

@ -87,6 +87,7 @@ struct Thread : public LinkedListNode<Thread>
u64 ticks_left;
u64 sleep_ticks_left;
u64 alarm_ticks_left { 0 };
Stack stack;
Stack kernel_stack;

View File

@ -25,6 +25,7 @@ set(SOURCES
src/termios.cpp
src/utime.cpp
src/strtod.cpp
src/math.cpp
src/sys/stat.cpp
src/sys/mman.cpp
src/sys/wait.cpp

0
libc/include/arpa/inet.h Normal file
View File

View File

@ -5,6 +5,28 @@
#include <bits/locale-cat.h>
struct lconv
{
char* decimal_point;
char* thousands_sep;
char* grouping;
char* int_curr_symbol;
char* currency_symbol;
char* mon_decimal_point;
char* mon_thousands_sep;
char* mon_grouping;
char* positive_sign;
char* negative_sign;
char int_frac_digits;
char frac_digits;
char p_cs_precedes;
char p_sep_by_space;
char n_cs_precedes;
char n_sep_by_space;
char p_sign_posn;
char n_sign_posn;
};
#ifdef __cplusplus
extern "C"
{
@ -13,6 +35,9 @@ extern "C"
// Query or set the current locale.
char* setlocale(int category, const char* locale);
// Query formatting information for the current locale.
struct lconv* localeconv(void);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,92 @@
/* math.h: Floating-point arithmetic functions. */
#ifndef _MATH_H
#define _MATH_H
typedef float float_t;
typedef double double_t;
#define FP_NAN 0
#define FP_INFINITE 1
#define FP_ZERO 2
#define FP_SUBNORMAL 3
#define FP_NORMAL 4
#define fpclassify(x) __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_ZERO, FP_SUBNORMAL, FP_ZERO, x)
#ifdef __cplusplus
extern "C"
{
#endif
double cos(double val);
float cosf(float val);
long double cosl(long double val);
double sin(double val);
float sinf(float val);
long double sinl(long double val);
double tan(double val);
float tanf(float val);
long double tanl(long double val);
double acos(double val);
float acosf(float val);
long double acosl(long double val);
double asin(double val);
float asinf(float val);
long double asinl(long double val);
double atan(double val);
float atanf(float val);
long double atanl(long double val);
double cosh(double val);
float coshf(float val);
long double coshl(long double val);
double sinh(double val);
float sinhf(float val);
long double sinhl(long double val);
double tanh(double val);
float tanhf(float val);
long double tanhl(long double val);
double log(double val);
float logf(float val);
long double logl(long double val);
double exp(double val);
float expf(float val);
long double expl(long double val);
double sqrt(double val);
float sqrtf(float val);
long double sqrtl(long double val);
double fabs(double val);
float fabsf(float val);
long double fabsl(long double val);
double floor(double val);
float floorf(float val);
long double floorl(long double val);
double ceil(double val);
float ceilf(float val);
long double ceill(long double val);
double log10(double val);
float log10f(float val);
long double log10l(long double val);
double fmod(double val1, double val2);
float fmodf(float val1, float val2);
long double fmodl(long double val1, long double val2);
double pow(double val1, double val2);
float powf(float val1, float val2);
long double powl(long double val1, long double val2);
double atan2(double val1, double val2);
float atan2f(float val1, float val2);
long double atan2l(long double val1, long double val2);
double frexp(double val1, int* val2);
float frexpf(float val1, int* val2);
long double frexpl(long double val1, int* val2);
double ldexp(double val1, int val2);
float ldexpf(float val1, int val2);
long double ldexpl(long double val1, int val2);
double modf(double val1, double* val2);
float modff(float val1, float* val2);
long double modfl(long double val1, long double* val2);
#ifdef __cplusplus
}
#endif
#endif

0
libc/include/netdb.h Normal file
View File

View File

View File

@ -198,6 +198,9 @@ extern "C"
/* Change a file's buffering mode to line buffered. */
void setlinebuf(FILE* stream);
/* Move a file's location across a file system. */
int rename(const char* oldpath, const char* newpath);
#ifdef __cplusplus
}
#endif

View File

@ -128,6 +128,9 @@ extern "C"
/* Clear all environment variables. */
int clearenv(void);
/* Add a new variable to the environment. */
int putenv(char* string);
/* Sort an array of arbitrary elements using a comparison function. */
void qsort(void* base, size_t nmemb, size_t size, int (*compar)(const void*, const void*));

View File

@ -98,6 +98,9 @@ extern "C"
/* Compare two null-terminated strings according to the current locale. */
int strcoll(const char* a, const char* b);
/* Transform a string according to the current locale. */
size_t strxfrm(char* dest, const char* src, size_t n);
#ifdef __cplusplus
}
#endif

View File

@ -14,10 +14,10 @@ extern "C"
int socket(int domain, int type, int protocol);
/* Bind a socket to an address. */
int bind(int sockfd, struct sockaddr* addr, socklen_t addrlen);
int bind(int sockfd, const struct sockaddr* addr, socklen_t addrlen);
/* Connect a socket to a remote address. */
int connect(int sockfd, struct sockaddr* addr, socklen_t addrlen);
int connect(int sockfd, const struct sockaddr* addr, socklen_t addrlen);
/* Start listening on a socket. */
int listen(int sockfd, int backlog);

View File

@ -7,6 +7,10 @@
#include <bits/struct_tm.h>
#include <bits/timespec.h>
typedef long int clock_t;
#define CLOCKS_PER_SEC 1000000
#ifdef __cplusplus
extern "C"
{
@ -42,9 +46,18 @@ extern "C"
/* Build a string representation of UNIX time. */
char* ctime_r(const time_t* tp, char buf[26]);
/* Convert broken-down time back into UNIX time. */
time_t mktime(struct tm* tm);
/* Format a string representation of broken-down time using a format string. */
size_t strftime(char* buf, size_t max, const char* format, const struct tm* tm);
/* Return the difference in seconds between two times. */
double difftime(time_t a, time_t b);
/* Estimate the CPU time used by a process. */
clock_t clock(void);
#ifdef __cplusplus
}
#endif

View File

@ -190,6 +190,12 @@ extern "C"
/* Truncate a file to a specific length. */
int ftruncate(int fd, size_t size);
/* Return the system page size. */
int getpagesize(void);
/* Schedule an alarm signal. */
unsigned int alarm(unsigned int seconds);
#ifdef __cplusplus
}
#endif

View File

@ -1,11 +1,13 @@
#include <bits/errno-return.h>
#include <errno.h>
#include <luna/HashTable.h>
#include <luna/ScopeGuard.h>
#include <luna/Vector.h>
#include <stdlib.h>
extern "C" char** environ;
Vector<char*> g_dynamic_env = {};
HashTable<char*> g_dynamic_vars = {};
bool env_is_dynamic { false };
/* If an environment variable matching key is found, stores its value in value and returns its index. Otherwise,
@ -41,22 +43,24 @@ static isize _findenv(const char* key, char** value)
return -1;
}
static void free_if_needed(char* element)
{
if (g_dynamic_vars.try_find(element))
{
g_dynamic_vars.try_remove(element);
free(element);
}
}
/* Move environ to a heap-allocated array. */
static Result<void> _try_move_env()
{
char** env = environ;
g_dynamic_env.clear();
auto guard = make_scope_guard([] {
for (auto element : g_dynamic_env)
{
if (element) free(element);
}
});
if (!env)
{
TRY(g_dynamic_env.try_append(nullptr));
guard.deactivate();
env_is_dynamic = true;
environ = g_dynamic_env.data();
return {};
@ -64,18 +68,12 @@ static Result<void> _try_move_env()
while (*env)
{
char* ptr = strdup(*(env++));
if (!ptr) return err(errno);
auto ptr_guard = make_scope_guard([=] { free(ptr); });
char* ptr = *(env++);
TRY(g_dynamic_env.try_append(ptr));
ptr_guard.deactivate();
}
TRY(g_dynamic_env.try_append(nullptr));
guard.deactivate();
env_is_dynamic = true;
environ = g_dynamic_env.data();
@ -105,7 +103,7 @@ static void _check_dynamic_env()
{
for (auto element : g_dynamic_env)
{
if (element) free(element);
if (element) free_if_needed(element);
}
}
}
@ -122,7 +120,7 @@ extern "C"
{
for (auto element : g_dynamic_env)
{
if (element) free(element);
if (element) free_if_needed(element);
}
g_dynamic_env.clear();
@ -152,9 +150,11 @@ extern "C"
if (_move_env() < 0) return -1;
}
g_dynamic_env.remove_at(index);
char* p = g_dynamic_env.remove_at(index);
_update_env();
free_if_needed(p);
return 0;
}
@ -188,12 +188,14 @@ extern "C"
if (index >= 0)
{
free(environ[index]);
free_if_needed(environ[index]);
environ[index] = str;
guard.deactivate();
return 0;
}
TRY_OR_SET_ERRNO(g_dynamic_vars.try_set(str), int, -1);
// Add a new NULL at the end of the array and replace the previous one with our string.
index = g_dynamic_env.size() - 1;
@ -206,6 +208,43 @@ extern "C"
return 0;
}
int putenv(char* string)
{
char* p = strchr(string, '=');
if (!p) return unsetenv(string);
size_t key_len = p - string;
char* key = strndup(string, key_len);
auto guard = make_scope_guard([key] { free(key); });
auto index = _findenv(key, nullptr);
_check_dynamic_env();
if (!env_is_dynamic)
{
if (_move_env() < 0) return -1;
}
if (index >= 0)
{
free_if_needed(environ[index]);
environ[index] = string;
return 0;
}
// Add a new NULL at the end of the array and replace the previous one with our string.
index = g_dynamic_env.size() - 1;
TRY_OR_SET_ERRNO(g_dynamic_env.try_append(nullptr), int, -1);
guard.deactivate();
_update_env();
environ[index] = string;
return 0;
}
char* getenv(const char* key)
{
char* result;

View File

@ -1,6 +1,30 @@
#include <limits.h>
#include <locale.h>
static char s_default_locale[] = "C";
static char s_empty_string[] = "";
static char s_decimal_point[] = ".";
static struct lconv s_lconv = {
.decimal_point = s_decimal_point,
.thousands_sep = s_empty_string,
.grouping = s_empty_string,
.int_curr_symbol = s_empty_string,
.currency_symbol = s_empty_string,
.mon_decimal_point = s_empty_string,
.mon_thousands_sep = s_empty_string,
.mon_grouping = s_empty_string,
.positive_sign = s_empty_string,
.negative_sign = s_empty_string,
.int_frac_digits = CHAR_MAX,
.frac_digits = CHAR_MAX,
.p_cs_precedes = CHAR_MAX,
.p_sep_by_space = CHAR_MAX,
.n_cs_precedes = CHAR_MAX,
.n_sep_by_space = CHAR_MAX,
.p_sign_posn = CHAR_MAX,
.n_sign_posn = CHAR_MAX,
};
extern "C"
{
@ -9,4 +33,9 @@ extern "C"
// FIXME: Set the current locale if <locale> is not NULL.
return s_default_locale;
}
struct lconv* localeconv(void)
{
return &s_lconv;
}
}

106
libc/src/math.cpp Normal file
View File

@ -0,0 +1,106 @@
#include <math.h>
// FIXME: Provide our own definitions instead of relying on the compiler's builtins.
#define WRAP_AROUND_BUILTIN(name) \
double name(double val) \
{ \
return __builtin_##name(val); \
} \
float name##f(float val) \
{ \
return __builtin_##name##f(val); \
} \
long double name##l(long double val) \
{ \
return __builtin_##name##l(val); \
}
#define WRAP_AROUND_BUILTIN2(name) \
double name(double val1, double val2) \
{ \
return __builtin_##name(val1, val2); \
} \
float name##f(float val1, float val2) \
{ \
return __builtin_##name##f(val1, val2); \
} \
long double name##l(long double val1, long double val2) \
{ \
return __builtin_##name##l(val1, val2); \
}
#define WRAP_AROUND_BUILTIN_WITH_PARAMETER_TYPE(name, type) \
double name(double val1, type val2) \
{ \
return __builtin_##name(val1, val2); \
} \
float name##f(float val1, type val2) \
{ \
return __builtin_##name##f(val1, val2); \
} \
long double name##l(long double val1, type val2) \
{ \
return __builtin_##name##l(val1, val2); \
}
#define WRAP_AROUND_BUILTIN_WITH_POINTER(name) \
double name(double val1, double* val2) \
{ \
return __builtin_##name(val1, val2); \
} \
float name##f(float val1, float* val2) \
{ \
return __builtin_##name##f(val1, val2); \
} \
long double name##l(long double val1, long double* val2) \
{ \
return __builtin_##name##l(val1, val2); \
}
extern "C"
{
WRAP_AROUND_BUILTIN(cos);
WRAP_AROUND_BUILTIN(sin);
WRAP_AROUND_BUILTIN(tan);
WRAP_AROUND_BUILTIN(acos);
WRAP_AROUND_BUILTIN(asin);
WRAP_AROUND_BUILTIN(atan);
WRAP_AROUND_BUILTIN(cosh);
WRAP_AROUND_BUILTIN(sinh);
WRAP_AROUND_BUILTIN(tanh);
WRAP_AROUND_BUILTIN(log);
WRAP_AROUND_BUILTIN(exp);
WRAP_AROUND_BUILTIN(sqrt);
WRAP_AROUND_BUILTIN(fabs);
WRAP_AROUND_BUILTIN(floor);
WRAP_AROUND_BUILTIN(ceil);
WRAP_AROUND_BUILTIN(log10);
WRAP_AROUND_BUILTIN2(fmod);
WRAP_AROUND_BUILTIN2(pow);
WRAP_AROUND_BUILTIN2(atan2);
WRAP_AROUND_BUILTIN_WITH_PARAMETER_TYPE(frexp, int*);
WRAP_AROUND_BUILTIN_WITH_PARAMETER_TYPE(ldexp, int);
WRAP_AROUND_BUILTIN_WITH_POINTER(modf);
}

View File

@ -752,4 +752,13 @@ extern "C"
{
setvbuf(stream, NULL, _IOLBF, 0);
}
int rename(const char* oldpath, const char* newpath)
{
// FIXME: Implement this atomically in-kernel.
unlink(newpath);
if (link(oldpath, newpath) < 0) return -1;
unlink(oldpath);
return 0;
}
}

View File

@ -15,6 +15,12 @@ extern "C"
return strcmp(a, b);
}
size_t strxfrm(char* dest, const char* src, size_t n)
{
strncpy(dest, src, n);
return n;
}
char* strerror(int errnum)
{
return const_cast<char*>(error_string(errnum));

View File

@ -11,13 +11,13 @@ extern "C"
__errno_return(rc, int);
}
int bind(int sockfd, struct sockaddr* addr, socklen_t addrlen)
int bind(int sockfd, const struct sockaddr* addr, socklen_t addrlen)
{
long rc = syscall(SYS_bind, sockfd, addr, addrlen);
__errno_return(rc, int);
}
int connect(int sockfd, struct sockaddr* addr, socklen_t addrlen)
int connect(int sockfd, const struct sockaddr* addr, socklen_t addrlen)
{
long rc = syscall(SYS_connect, sockfd, addr, addrlen);
__errno_return(rc, int);

View File

@ -3,6 +3,7 @@
#include <luna/Format.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/resource.h>
#include <sys/syscall.h>
#include <time.h>
#include <unistd.h>
@ -31,6 +32,13 @@ static int day_of_week(int year, int mon, int day)
return (year + year / 4 - year / 100 + year / 400 + t[mon - 1] + day) % 7;
}
// https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_16
static constexpr u64 broken_down_to_unix(u64 year, u64 yday, u64 hour, u64 min, u64 sec)
{
return sec + min * 60 + hour * 3600 + yday * 86400 + (year - 70) * 31536000 + ((year - 69) / 4) * 86400 -
((year - 1) / 100) * 86400 + ((year + 299) / 400) * 86400;
}
static void time_to_struct_tm(time_t time, struct tm* result)
{
result->tm_isdst = 0; // No DST/timezone support for now.
@ -167,4 +175,29 @@ extern "C"
return 0;
}
time_t mktime(struct tm* tm)
{
// FIXME: Check if the tm structure is valid.
time_t result = broken_down_to_unix(tm->tm_year, make_yday(tm->tm_year, tm->tm_mon + 1) + (tm->tm_mday - 1),
tm->tm_hour, tm->tm_min, tm->tm_sec);
tm->tm_yday = make_yday(tm->tm_year + 1900, tm->tm_mon + 1) + (tm->tm_mday - 1);
tm->tm_wday = day_of_week(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday);
return result;
}
double difftime(time_t a, time_t b)
{
return (double)(a - b);
}
clock_t clock(void)
{
struct rusage ru;
if (getrusage(RUSAGE_SELF, &ru) < 0) return (clock_t)-1;
return ru.ru_utime.tv_sec * CLOCKS_PER_SEC + ru.ru_utime.tv_usec;
}
}

View File

@ -8,6 +8,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/utsname.h>
@ -510,4 +511,14 @@ extern "C"
long rc = syscall(SYS_ftruncate, fd, size);
__errno_return(rc, int);
}
int getpagesize(void)
{
return PAGE_SIZE;
}
unsigned int alarm(unsigned int seconds)
{
return (unsigned int)syscall(SYS_alarm, seconds);
}
}

View File

@ -8,7 +8,7 @@
_e(umount) _e(pstat) _e(getrusage) _e(symlinkat) _e(readlinkat) _e(umask) _e(linkat) _e(faccessat) \
_e(pivot_root) _e(sigreturn) _e(sigaction) _e(kill) _e(sigprocmask) _e(setpgid) _e(isatty) \
_e(getpgid) _e(socket) _e(bind) _e(connect) _e(listen) _e(accept) _e(poll) _e(msync) \
_e(truncate) _e(ftruncate) _e(utimensat)
_e(truncate) _e(ftruncate) _e(utimensat) _e(alarm)
enum Syscalls
{

View File

@ -1,62 +1,70 @@
#pragma once
#define EPERM 1 // Operation not permitted
#define ENOENT 2 // No such file or directory
#define ESRCH 3 // No such process
#define EINTR 4 // Interrupted system call
#define EIO 5 // Input/output error
#define ENXIO 6 // No such device or address
#define E2BIG 7 // Argument list too long
#define ENOEXEC 8 // Exec format error
#define EBADF 9 // Bad file descriptor
#define ECHILD 10 // No child processes
#define EAGAIN 11 // Resource temporarily unavailable
#define EWOULDBLOCK 11 // Resource temporarily unavailable
#define ENOMEM 12 // Cannot allocate memory
#define EACCES 13 // Permission denied
#define EFAULT 14 // Bad address
#define ENOTBLK 15 // Block device required
#define EBUSY 16 // Device or resource busy
#define EEXIST 17 // File exists
#define EXDEV 18 // Invalid cross-device link
#define ENODEV 19 // No such device
#define ENOTDIR 20 // Not a directory
#define EISDIR 21 // Is a directory
#define EINVAL 22 // Invalid argument
#define ENFILE 23 // Too many open files in system
#define EMFILE 24 // Too many open files
#define ENOTTY 25 // Inappropriate ioctl for device
#define ETXTBSY 26 // Text file busy
#define EFBIG 27 // File too large
#define ENOSPC 28 // No space left on device
#define ESPIPE 29 // Illegal seek
#define EROFS 30 // Read-only file system
#define EMLINK 31 // Too many links
#define EPIPE 32 // Broken pipe
#define EDOM 33 // Numerical argument out of domain
#define ERANGE 34 // Numerical result out of range
#define EDEADLK 35 // Resource deadlock avoided
#define ENAMETOOLONG 36 // File name too long
#define ENOLCK 37 // No locks available
#define ENOSYS 38 // Function not implemented
#define ENOTEMPTY 39 // Directory not empty
#define ELOOP 40 // Too many levels of symbolic links
#define ENOMSG 42 // No message of desired type
#define EOVERFLOW 75 // Value too large for defined data type
#define EILSEQ 84 // Invalid or incomplete multibyte or wide character
#define ENOTSOCK 88 // Socket operation on non-socket
#define EDESTADDRREQ 89 // Destination address required
#define EPROTOTYPE 91 // Protocol wrong type for socket
#define ENOTSUP 95 // Operation not supported
#define EOPNOTSUPP 95 // Operation not supported
#define EAFNOSUPPORT 97 // Address family not supported by protocol
#define EADDRINUSE 98 // Address already in use
#define EADDRNOTAVAIL 99 // Cannot assign requested address
#define ENETRESET 102 // Network dropped connection on reset
#define ECONNRESET 104 // Connection reset by peer
#define EISCONN 106 // Transport endpoint is already connected
#define ENOTCONN 107 // Transport endpoint is not connected
#define ETIMEDOUT 110 // Connection timed out
#define ECONNREFUSED 111 // Connection refused
#define EALREADY 114 // Operation already in progress
#define EINPROGRESS 115 // Operation now in progress
#define EPERM 1 // Operation not permitted
#define ENOENT 2 // No such file or directory
#define ESRCH 3 // No such process
#define EINTR 4 // Interrupted system call
#define EIO 5 // Input/output error
#define ENXIO 6 // No such device or address
#define E2BIG 7 // Argument list too long
#define ENOEXEC 8 // Exec format error
#define EBADF 9 // Bad file descriptor
#define ECHILD 10 // No child processes
#define EAGAIN 11 // Resource temporarily unavailable
#define EWOULDBLOCK 11 // Resource temporarily unavailable
#define ENOMEM 12 // Cannot allocate memory
#define EACCES 13 // Permission denied
#define EFAULT 14 // Bad address
#define ENOTBLK 15 // Block device required
#define EBUSY 16 // Device or resource busy
#define EEXIST 17 // File exists
#define EXDEV 18 // Invalid cross-device link
#define ENODEV 19 // No such device
#define ENOTDIR 20 // Not a directory
#define EISDIR 21 // Is a directory
#define EINVAL 22 // Invalid argument
#define ENFILE 23 // Too many open files in system
#define EMFILE 24 // Too many open files
#define ENOTTY 25 // Inappropriate ioctl for device
#define ETXTBSY 26 // Text file busy
#define EFBIG 27 // File too large
#define ENOSPC 28 // No space left on device
#define ESPIPE 29 // Illegal seek
#define EROFS 30 // Read-only file system
#define EMLINK 31 // Too many links
#define EPIPE 32 // Broken pipe
#define EDOM 33 // Numerical argument out of domain
#define ERANGE 34 // Numerical result out of range
#define EDEADLK 35 // Resource deadlock avoided
#define ENAMETOOLONG 36 // File name too long
#define ENOLCK 37 // No locks available
#define ENOSYS 38 // Function not implemented
#define ENOTEMPTY 39 // Directory not empty
#define ELOOP 40 // Too many levels of symbolic links
#define ENOMSG 42 // No message of desired type
#define EOVERFLOW 75 // Value too large for defined data type
#define EILSEQ 84 // Invalid or incomplete multibyte or wide character
#define ENOTSOCK 88 // Socket operation on non-socket
#define EDESTADDRREQ 89 // Destination address required
#define EMSGSIZE 90 // Message too long
#define EPROTOTYPE 91 // Protocol wrong type for socket
#define ENOPROTOOPT 92 // Protocol not available
#define EPROTONOSUPPORT 93 // Protocol not supported
#define ENOTSUP 95 // Operation not supported
#define EOPNOTSUPP 95 // Operation not supported
#define EAFNOSUPPORT 97 // Address family not supported by protocol
#define EADDRINUSE 98 // Address already in use
#define EADDRNOTAVAIL 99 // Cannot assign requested address
#define ENETDOWN 100 // Network is down
#define ENETUNREACH 101 // Network is unreachable
#define ENETRESET 102 // Network dropped connection on reset
#define ECONNABORTED 103 // Software caused connection abort
#define ECONNRESET 104 // Connection reset by peer
#define ENOBUFS 105 // No buffer space available
#define EISCONN 106 // Transport endpoint is already connected
#define ENOTCONN 107 // Transport endpoint is not connected
#define ETIMEDOUT 110 // Connection timed out
#define ECONNREFUSED 111 // Connection refused
#define EHOSTUNREACH 113 // No route to host
#define EALREADY 114 // Operation already in progress
#define EINPROGRESS 115 // Operation now in progress

View File

@ -17,10 +17,14 @@
#include <sys/mman.h>
#endif
// Otherwise, this is defined in libstdc++.
#ifdef USE_FREESTANDING
namespace std
{
const nothrow_t nothrow;
}
#endif
static constexpr int BLOCK_USED = 1 << 0;
static constexpr int BLOCK_START_MEM = 1 << 1;
@ -417,6 +421,8 @@ void dump_heap_usage()
dbgln("-- Heap memory in use: %zu bytes", alloc_used);
}
// Otherwise, this is defined in libstdc++.
#ifdef USE_FREESTANDING
void* operator new(usize size, const std::nothrow_t&) noexcept
{
return malloc_impl(size).value_or(nullptr);
@ -446,3 +452,4 @@ void operator delete[](void* p, usize) noexcept
{
free_impl(p);
}
#endif

View File

@ -63,6 +63,14 @@ const char* error_string(int error)
case EADDRNOTAVAIL: return "Cannot assign requested address";
case ECONNREFUSED: return "Connection refused";
case EINPROGRESS: return "Operation now in progress";
case ECONNABORTED: return "Software caused connection abort";
case EHOSTUNREACH: return "No route to host";
case EMSGSIZE: return "Message too long";
case ENETDOWN: return "Network is down";
case ENETUNREACH: return "Network is unreachable";
case ENOBUFS: return "No buffer space available";
case ENOPROTOOPT: return "Protocol not available";
case EPROTONOSUPPORT: return "Protocol not supported";
default: return "Unknown error";
}
}
@ -132,6 +140,14 @@ const char* error_name(int error)
ERROR(EADDRNOTAVAIL);
ERROR(ECONNREFUSED);
ERROR(EINPROGRESS);
ERROR(ECONNABORTED);
ERROR(EHOSTUNREACH);
ERROR(EMSGSIZE);
ERROR(ENETDOWN);
ERROR(ENETUNREACH);
ERROR(ENOBUFS);
ERROR(ENOPROTOOPT);
ERROR(EPROTONOSUPPORT);
default: return nullptr;
}

View File

@ -72,6 +72,35 @@ TestResult test_setenv_before_and_after_manual_environ_modification()
test_success;
}
TestResult test_putenv()
{
clearenv();
char lit[] = "NAME=VALUE";
validate(putenv(lit) == 0);
char* value = getenv("NAME");
validate(value && !strcmp(value, "VALUE"));
lit[0] = 'F';
value = getenv("NAME");
validate(!value);
value = getenv("FAME");
validate(value && !strcmp(value, "VALUE"));
validate(unsetenv("FAME") == 0);
value = getenv("FAME");
validate(!value);
validate(!strcmp(lit, "FAME=VALUE"));
test_success;
}
Result<void> test_main()
{
test_prelude;
@ -80,6 +109,7 @@ Result<void> test_main()
run_test(test_setenv_dont_overwrite);
run_test(test_unsetenv);
run_test(test_setenv_before_and_after_manual_environ_modification);
run_test(test_putenv);
return {};
}

View File

@ -1,6 +1,6 @@
diff --color -rN -u gcc-12.2.0/config.sub build/gcc-12.2.0/config.sub
diff --color -rN -u vanilla/gcc-12.2.0/config.sub gcc-12.2.0/config.sub
--- a/gcc-12.2.0/config.sub 2022-08-19 10:09:52.128656687 +0200
+++ b/gcc-12.2.0/config.sub 2022-10-02 11:27:45.660055384 +0200
+++ b/gcc-12.2.0/config.sub 2023-08-08 20:42:05.032843544 +0200
@@ -1723,7 +1723,7 @@
| hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \
| sym* | plan9* | psp* | sim* | xray* | os68k* | v88r* \
@ -10,9 +10,9 @@ diff --color -rN -u gcc-12.2.0/config.sub build/gcc-12.2.0/config.sub
| mpw* | magic* | mmixware* | mon960* | lnews* \
| amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \
| aos* | aros* | cloudabi* | sortix* | twizzler* \
diff --color -rN -u gcc-12.2.0/fixincludes/mkfixinc.sh build/gcc-12.2.0/fixincludes/mkfixinc.sh
diff --color -rN -u vanilla/gcc-12.2.0/fixincludes/mkfixinc.sh gcc-12.2.0/fixincludes/mkfixinc.sh
--- a/gcc-12.2.0/fixincludes/mkfixinc.sh 2022-08-19 10:09:52.160657095 +0200
+++ b/gcc-12.2.0/fixincludes/mkfixinc.sh 2022-10-02 11:27:45.662055397 +0200
+++ b/gcc-12.2.0/fixincludes/mkfixinc.sh 2023-08-08 20:42:05.034843561 +0200
@@ -12,6 +12,8 @@
# Check for special fix rules for particular targets
case $machine in
@ -22,18 +22,18 @@ diff --color -rN -u gcc-12.2.0/fixincludes/mkfixinc.sh build/gcc-12.2.0/fixinclu
i?86-*-mingw32* | \
x86_64-*-mingw32* | \
powerpc-*-eabisim* | \
diff --color -rN -u gcc-12.2.0/gcc/config/i386/x86_64-luna-kernel build/gcc-12.2.0/gcc/config/i386/x86_64-luna-kernel
--- a/dev/null 1970-01-01 01:00:00.000000000 +0100
+++ b/gcc-12.2.0/gcc/config/i386/x86_64-luna-kernel 2022-10-02 11:45:30.955856133 +0200
diff --color -rN -u vanilla/gcc-12.2.0/gcc/config/i386/x86_64-luna-kernel gcc-12.2.0/gcc/config/i386/x86_64-luna-kernel
--- a/gcc-12.2.0/gcc/config/i386/x86_64-luna-kernel 1970-01-01 01:00:00.000000000 +0100
+++ b/gcc-12.2.0/gcc/config/i386/x86_64-luna-kernel 2023-08-08 20:42:05.038843594 +0200
@@ -0,0 +1,4 @@
+#Add libgcc multilib variant without red-zone requirement, for use in the kernel
+
+MULTILIB_OPTIONS += mno-red-zone
+MULTILIB_DIRNAMES += no-red-zone
\ No newline at end of file
diff --color -rN -u gcc-12.2.0/gcc/config/luna.h build/gcc-12.2.0/gcc/config/luna.h
--- a/dev/null 1970-01-01 01:00:00.000000000 +0100
+++ b/gcc-12.2.0/gcc/config/luna.h 2022-10-02 11:27:45.663055404 +0200
diff --color -rN -u vanilla/gcc-12.2.0/gcc/config/luna.h gcc-12.2.0/gcc/config/luna.h
--- a/gcc-12.2.0/gcc/config/luna.h 1970-01-01 01:00:00.000000000 +0100
+++ b/gcc-12.2.0/gcc/config/luna.h 2023-08-08 20:42:05.040843610 +0200
@@ -0,0 +1,36 @@
+#undef TARGET_LUNA
+#define TARGET_LUNA 1
@ -71,11 +71,9 @@ diff --color -rN -u gcc-12.2.0/gcc/config/luna.h build/gcc-12.2.0/gcc/config/lun
+ } while (0);
+
+#undef LINK_SPEC
+#define LINK_SPEC "-z max-page-size=4096"
\ No newline at end of file
diff --color -rN -u gcc-12.2.0/gcc/config.gcc build/gcc-12.2.0/gcc/config.gcc
diff --color -rN -u vanilla/gcc-12.2.0/gcc/config.gcc gcc-12.2.0/gcc/config.gcc
--- a/gcc-12.2.0/gcc/config.gcc 2022-08-19 10:09:52.552662114 +0200
+++ b/gcc-12.2.0/gcc/config.gcc 2022-10-02 11:45:18.311797546 +0200
+++ b/gcc-12.2.0/gcc/config.gcc 2023-08-08 20:42:05.044843643 +0200
@@ -895,6 +895,12 @@
;;
esac
@ -103,9 +101,9 @@ diff --color -rN -u gcc-12.2.0/gcc/config.gcc build/gcc-12.2.0/gcc/config.gcc
x86_64-*-rtems*)
tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h newlib-stdint.h i386/i386elf.h i386/x86-64.h i386/rtemself.h rtems.h"
;;
diff --color -rN -u gcc-12.2.0/libgcc/config.host build/gcc-12.2.0/libgcc/config.host
diff --color -rN -u vanilla/gcc-12.2.0/libgcc/config.host gcc-12.2.0/libgcc/config.host
--- a/gcc-12.2.0/libgcc/config.host 2022-08-19 10:09:54.664689148 +0200
+++ b/gcc-12.2.0/libgcc/config.host 2022-10-02 11:27:45.671055461 +0200
+++ b/gcc-12.2.0/libgcc/config.host 2023-08-08 20:42:05.046843660 +0200
@@ -783,6 +783,14 @@
;;
i[34567]86-*-lynxos*)
@ -121,9 +119,9 @@ diff --color -rN -u gcc-12.2.0/libgcc/config.host build/gcc-12.2.0/libgcc/config
i[34567]86-*-nto-qnx*)
tmake_file="$tmake_file i386/t-nto t-libgcc-pic"
extra_parts=crtbegin.o
diff --color -rN -u gcc-12.2.0/libgcc/libgcov.h build/gcc-12.2.0/libgcc/libgcov.h
diff --color -rN -u vanilla/gcc-12.2.0/libgcc/libgcov.h gcc-12.2.0/libgcc/libgcov.h
--- a/gcc-12.2.0/libgcc/libgcov.h 2022-08-19 10:09:54.728689966 +0200
+++ b/gcc-12.2.0/libgcc/libgcov.h 2022-10-02 11:41:48.571807335 +0200
+++ b/gcc-12.2.0/libgcc/libgcov.h 2023-08-08 20:42:05.048843677 +0200
@@ -194,6 +194,7 @@
#endif
@ -132,3 +130,79 @@ diff --color -rN -u gcc-12.2.0/libgcc/libgcov.h build/gcc-12.2.0/libgcc/libgcov.
/* Structures embedded in coveraged program. The structures generated
by write_profile must match these. */
diff --color -rN -u vanilla/gcc-12.2.0/libstdc++-v3/acinclude.m4 gcc-12.2.0/libstdc++-v3/acinclude.m4
--- a/gcc-12.2.0/libstdc++-v3/acinclude.m4 2022-08-19 10:09:55.380698313 +0200
+++ b/gcc-12.2.0/libstdc++-v3/acinclude.m4 2023-08-08 21:08:00.777765701 +0200
@@ -1356,6 +1356,10 @@
ac_has_nanosleep=yes
ac_has_sched_yield=yes
;;
+ luna*)
+ ac_has_clock_monotonic=yes
+ ac_has_clock_realtime=yes
+ ;;
# VxWorks has nanosleep as soon as the kernel is configured with
# INCLUDE_POSIX_TIMERS, which is normally/most-often the case.
vxworks*)
@@ -2421,7 +2425,7 @@
dragonfly* | freebsd*)
enable_clocale_flag=dragonfly
;;
- openbsd*)
+ openbsd* | luna*)
enable_clocale_flag=newlib
;;
*)
diff --color -rN -u vanilla/gcc-12.2.0/libstdc++-v3/configure gcc-12.2.0/libstdc++-v3/configure
--- a/gcc-12.2.0/libstdc++-v3/configure 2022-08-19 10:09:55.416698774 +0200
+++ b/gcc-12.2.0/libstdc++-v3/configure 2023-08-09 11:34:54.810282202 +0200
@@ -16481,6 +16481,9 @@
openbsd*)
enable_clocale_flag=newlib
;;
+ luna*)
+ enable_clocale_flag=generic
+ ;;
*)
if test x"$with_newlib" = x"yes"; then
enable_clocale_flag=newlib
@@ -20493,6 +20496,10 @@
ac_has_nanosleep=yes
ac_has_sched_yield=yes
;;
+ luna*)
+ ac_has_clock_monotonic=yes
+ ac_has_clock_realtime=yes
+ ;;
# VxWorks has nanosleep as soon as the kernel is configured with
# INCLUDE_POSIX_TIMERS, which is normally/most-often the case.
vxworks*)
diff --color -rN -u vanilla/gcc-12.2.0/libstdc++-v3/configure.host gcc-12.2.0/libstdc++-v3/configure.host
--- a/gcc-12.2.0/libstdc++-v3/configure.host 2022-08-19 10:09:55.420698825 +0200
+++ b/gcc-12.2.0/libstdc++-v3/configure.host 2023-08-09 11:35:05.734185945 +0200
@@ -306,6 +306,9 @@
vxworks*)
os_include_dir="os/vxworks"
;;
+ luna*)
+ os_include_dir="os/generic"
+ ;;
*)
os_include_dir="os/generic"
;;
diff --color -rN -u vanilla/gcc-12.2.0/libstdc++-v3/crossconfig.m4 gcc-12.2.0/libstdc++-v3/crossconfig.m4
--- a/gcc-12.2.0/libstdc++-v3/crossconfig.m4 2022-08-19 10:09:55.420698825 +0200
+++ b/gcc-12.2.0/libstdc++-v3/crossconfig.m4 2023-08-08 21:16:12.897071194 +0200
@@ -277,6 +277,12 @@
GLIBCXX_CHECK_MATH_SUPPORT
GLIBCXX_CHECK_STDLIB_SUPPORT
;;
+ *-luna*)
+ GLIBCXX_CHECK_COMPILER_FEATURES
+ GLIBCXX_CHECK_LINKER_FEATURES
+ GLIBCXX_CHECK_MATH_SUPPORT
+ GLIBCXX_CHECK_STDLIB_SUPPORT
+ ;;
*-vxworks*)
AC_DEFINE(HAVE_ACOSF)
AC_DEFINE(HAVE_ASINF)

View File

@ -29,7 +29,7 @@ source ports/$PORT_NAME/PACKAGE
[ -z ${url+x} ] && show_error "error: The port's PACKAGE file does not have a 'url' key."
if ! [ -z ${dependencies+x} ]; then
echo "Installing dependencies of $name: ($dependencies)"
echo "Installing dependencies of $name: (${dependencies[@]})"
for dep in ${dependencies[@]}; do
tools/install-package.sh $dep
done
@ -48,15 +48,22 @@ case $format in
tar)
[ -z ${output+x} ] && show_error "error: The 'tar' download format needs an 'output' key."
[ -z ${sha256sum+x} ] && show_error "error: The 'tar' download format needs a 'sha256sum' key."
echo "Downloading tarball for $name..."
wget $url --quiet
if ! [ -f $output ]; then
echo "Downloading tarball for $name..."
wget $url --quiet
else
echo "Using cached tarball for $name."
fi
echo "$sha256sum $output" | sha256sum -c
tar xf $output
rm $output
;;
git)
echo "Cloning repository for $name..."
git clone $url $srcdir
if ! [ -d $srcdir]; then
echo "Cloning repository for $name..."
git clone $url $srcdir
else
echo "Using local repository for $name."
fi
if ! [ -z ${tag+x} ]; then
cd $srcdir
git checkout $tag
@ -68,12 +75,14 @@ case $format in
;;
esac
if ! [ "$set_cc_variables" = "no" ]; then
export CC=x86_64-luna-gcc
export CXX=x86_64-luna-g++
export PKG_CONFIG=luna-pkg-config
export CC_FOR_BUILD=gcc
export CXX_FOR_BUILD=g++
export PKG_CONFIG_FOR_BUILD=pkg-config
fi
mkdir -p $builddir
cd $builddir

View File

@ -47,7 +47,7 @@ unset CXX
unset LD
unset AR
../gcc-$LUNA_GCC_VERSION_REQUIRED/configure --prefix="$BUILD_PREFIX" --target=$BUILD_TARGET --disable-nls --with-sysroot=$BUILD_SYSROOT --enable-languages=c,c++ --without-headers
../gcc-$LUNA_GCC_VERSION_REQUIRED/configure --prefix="$BUILD_PREFIX" --target=$BUILD_TARGET --disable-nls --with-sysroot=$BUILD_SYSROOT --enable-languages=c,c++
echo Building GCC...
@ -58,3 +58,10 @@ echo Installing GCC...
make install-gcc
make install-target-libgcc
mkdir -p $LUNA_BUILD_DIR
cmake -S $LUNA_ROOT -B $LUNA_BUILD_DIR -G "$LUNA_CMAKE_GENERATOR_NAME"
cmake --build $LUNA_BUILD_DIR --target libc
make all-target-libstdc++-v3 CXXFLAGS_FOR_TARGET="-fno-exceptions" -j$(nproc)
make DESTDIR=$LUNA_BASE/usr install-target-libstdc++-v3