diff --git a/Drivers/include/errno.h b/Drivers/include/errno.h index ee601518..e9dfcabd 100644 --- a/Drivers/include/errno.h +++ b/Drivers/include/errno.h @@ -25,581 +25,567 @@ * Full list: * https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/basedefs/errno.h.html */ -typedef enum -{ - /** - * No Error - */ - EOK = 0, - - /** - * Argument list too long. The sum of the number of bytes used by the - * new process image's argument list and environment list is greater - * than the system-imposed limit of {ARG_MAX} bytes. - * or: - * Lack of space in an output buffer. - * or: - * Argument is greater than the system-imposed maximum. - */ - E2BIG = 1, - - /** - * Permission denied. An attempt was made to access a file in a way - * forbidden by its file access permissions. - */ - EACCES = 2, - - /** - * Address in use. The specified address is in use. - */ - EADDRINUSE = 3, - - /** - * Address not available. The specified address is not available from - * the local system. - */ - EADDRNOTAVAIL = 4, - - /** - * Address family not supported. The implementation does not support - * the specified address family, or the specified address is not a - * valid address for the address family of the specified socket. - */ - EAFNOSUPPORT = 5, - - /** - * Resource temporarily unavailable. This is a temporary condition - * and later calls to the same routine may complete normally. - */ - EAGAIN = 6, - - /** - * Connection already in progress. A connection request is already in - * progress for the specified socket. - */ - EALREADY = 7, - - /** - * Bad file descriptor. A file descriptor argument is out of range, - * refers to no open file, or a read (write) request is made to a - * file that is only open for writing (reading). - */ - EBADF = 8, - - /** - * Bad message. During a read(), getmsg(), getpmsg(), or ioctl() - * I_RECVFD request to a STREAMS device, a message arrived at the - * head of the STREAM that is inappropriate for the function - * receiving the message. - * read() - * Message waiting to be read on a STREAM is not a data message. - * getmsg() or getpmsg() - * A file descriptor was received instead of a control message. - * ioctl() - * Control or data information was received instead of a file - * descriptor when I_RECVFD was specified. - */ - EBADMSG = 9, - - /** - * Resource busy. An attempt was made to make use of a system - * resource that is not currently available, as it is being - * used by another process in a manner that would have - * conflicted with the request being made by this process. - */ - EBUSY = 10, - - /** - * Operation canceled. The associated asynchronous operation was - * canceled before completion. - */ - ECANCELED = 11, - - /** - * No child process. A wait(), waitid(), or waitpid() function was - * executed by a process that had no existing or unwaited-for - * child process. - */ - ECHILD = 12, - - /** - * Connection aborted. The connection has been aborted. - */ - ECONNABORTED = 13, - - /** - * Connection refused. An attempt to connect to a socket was refused - * because there was no process listening or because the queue of - * connection requests was full and the underlying protocol does not - * support retransmissions. - */ - ECONNREFUSED = 14, - - /** - * Connection reset. The connection was forcibly closed by the peer. - */ - ECONNRESET = 15, - - /** - * Resource deadlock would occur. An attempt was made to lock a system - * resource that would have resulted in a deadlock situation. - */ - EDEADLK = 16, - - /** - * Destination address required. No bind address was established. - */ - EDESTADDRREQ = 17, - - /** - * Domain error. An input argument is outside the defined domain of the - * mathematical function (defined in the ISO C standard). - */ - EDOM = 18, - - /** - * Reserved. - */ - EDQUOT = 19, - - /** - * File exists. An existing file was mentioned in an inappropriate - * context; for example, as a new link name in the link() function. - */ - EEXIST = 20, - - /** - * Bad address. The system detected an invalid address in attempting - * to use an argument of a call. The reliable detection of this error - * cannot be guaranteed, and when not detected may result in the - * generation of a signal, indicating an address violation, which is - * sent to the process. - */ - EFAULT = 21, - - /** - * File too large. The size of a file would exceed the maximum file - * size of an implementation or offset maximum established in the - * corresponding file description. - */ - EFBIG = 22, - - /** - * Host is unreachable. The destination host cannot be reached - * (probably because the host is down or a remote router cannot - * reach it). - */ - EHOSTUNREACH = 23, - - /** - * Identifier removed. Returned during XSI interprocess communication - * if an identifier has been removed from the system. - */ - EIDRM = 24, - - /** - * Illegal byte sequence. A wide-character code has been detected that - * does not correspond to a valid character, or a byte sequence does - * not form a valid wide-character code (defined in the ISO C standard). - */ - EILSEQ = 25, - - /** - * Operation in progress. This code is used to indicate that an - * asynchronous operation has not yet completed. - * or: - * O_NONBLOCK is set for the socket file descriptor and the connection - * cannot be immediately established. - */ - EINPROGRESS = 26, - - /** - * Interrupted function call. An asynchronous signal was caught by the - * process during the execution of an interruptible function. If the - * signal handler performs a normal return, the interrupted function - * call may return this condition (see the Base Definitions volume - * of POSIX.1-2017, ). - */ - EINTR = 27, - - /** - * Invalid argument. Some invalid argument was supplied; for example, - * specifying an undefined signal in a signal() function or a - * kill() function. - */ - EINVAL = 28, - - /** - * Input/output error. Some physical input or output error has occurred. - * This error may be reported on a subsequent operation on the same - * file descriptor. Any other error-causing operation on the same file - * descriptor may cause the [EIO] error indication to be lost. - */ - EIO = 29, - - /** - * Socket is connected. The specified socket is already connected. - */ - EISCONN = 30, - - /** - * Is a directory. An attempt was made to open a directory with write - * mode specified. - */ - EISDIR = 31, - - /** - * Symbolic link loop. A loop exists in symbolic links encountered - * during pathname resolution. This error may also be returned if - * more than {SYMLOOP_MAX} symbolic links are encountered during - * pathname resolution. - */ - ELOOP = 32, - - /** - * File descriptor value too large or too many open streams. An - * attempt was made to open a file descriptor with a value greater - * than or equal to {OPEN_MAX}, or an attempt was made to open more - * than the maximum number of streams allowed in the process. - */ - EMFILE = 33, - - /** - * Too many links. An attempt was made to have the link count of a - * single file exceed {LINK_MAX}. - */ - EMLINK = 34, - - /** - * Message too large. A message sent on a transport provider was - * larger than an internal message buffer or some other network limit. - * or: - * Inappropriate message buffer length. - */ - EMSGSIZE = 35, - - /** - * Reserved. - */ - EMULTIHOP = 36, - - /** - * Filename too long. The length of a pathname exceeds {PATH_MAX} and - * the implementation considers this to be an error, or a pathname - * component is longer than {NAME_MAX}. This error may also occur - * when pathname substitution, as a result of encountering a - * symbolic link during pathname resolution, results in a pathname - * string the size of which exceeds {PATH_MAX}. - */ - ENAMETOOLONG = 37, - - /** - * Network is down. The local network interface used to reach the - * destination is down. - */ - ENETDOWN = 38, - - /** - * The connection was aborted by the network. - */ - ENETRESET = 39, - - /** - * Network unreachable. No route to the network is present. - */ - ENETUNREACH = 40, - - /** - * Too many files open in system. Too many files are currently open - * in the system. The system has reached its predefined limit for - * simultaneously open files and temporarily cannot accept requests - * to open another one. - */ - ENFILE = 41, - - /** - * No buffer space available. Insufficient buffer resources were - * available in the system to perform the socket operation. - */ - ENOBUFS = 42, - - /** - * No message available. No message is available on the STREAM head - * read queue. - */ - ENODATA = 43, - - /** - * No such device. An attempt was made to apply an inappropriate - * function to a device; for example, trying to read a write-only - * device such as a printer. - */ - ENODEV = 44, - - /** - * No such file or directory. A component of a specified pathname - * does not exist, or the pathname is an empty string. - */ - ENOENT = 45, - - /** - * Executable file format error. A request is made to execute a file - * that, although it has appropriate privileges, is not in the - * format required by the implementation for executable files. - */ - ENOEXEC = 46, - - /** - * No locks available. A system-imposed limit on the number of - * simultaneous file and record locks has been reached and no more - * are currently available. - */ - ENOLCK = 47, - - /** - * Reserved. - */ - ENOLINK = 48, - - /** - * Not enough space. The new process image requires more memory than - * is allowed by the hardware or system-imposed memory management - * constraints. - */ - ENOMEM = 49, - - /** - * No message of the desired type. The message queue does not contain - * a message of the required type during XSI interprocess communication. - */ - ENOMSG = 50, - - /** - * Protocol not available. The protocol option specified to - * setsockopt() is not supported by the implementation. - */ - ENOPROTOOPT = 51, - - /** - * No space left on a device. During the write() function on a - * regular file or when extending a directory, there is no free - * space left on the device. - */ - ENOSPC = 52, - - /** - * No STREAM resources. Insufficient STREAMS memory resources are - * available to perform a STREAMS-related function. This is a - * temporary condition; it may be recovered from if other - * processes release resources. - */ - ENOSR = 53, - - /** - * Not a STREAM. A STREAM function was attempted on a file descriptor - * that was not associated with a STREAMS device. - */ - ENOSTR = 54, - - /** - * Functionality not supported. An attempt was made to use optional - * functionality that is not supported in this implementation. - */ - ENOSYS = 55, - - /** - * Socket not connected. The socket is not connected. - */ - ENOTCONN = 56, - - /** - * Not a directory. A component of the specified pathname exists, but - * it is not a directory, when a directory was expected; or an - * attempt was made to create a non-directory file, and the specified - * pathname contains at least one non- \ character and ends - * with one or more trailing \ characters. - */ - ENOTDIR = 57, - - /** - * Directory not empty. A directory other than an empty directory - * was supplied when an empty directory was expected. - */ - ENOTEMPTY = 58, - - /** - * State not recoverable. The state protected by a robust mutex - * is not recoverable. - */ - ENOTRECOVERABLE = 59, - - /** - * Not a socket. The file descriptor does not refer to a socket. - */ - ENOTSOCK = 60, - - /** - * Not supported. The implementation does not support the requested - * feature or value. - */ - ENOTSUP = 61, - - /** - * Inappropriate I/O control operation. A control function has been - * attempted for a file or special file for which the operation - * is inappropriate. - */ - ENOTTY = 62, - - /** - * No such device or address. Input or output on a special file - * refers to a device that does not exist, or makes a request - * beyond the capabilities of the device. It may also occur when, - * for example, a tape drive is not on-line. - */ - ENXIO = 63, - - /** - * Operation not supported on socket. The type of socket (address - * family or protocol) does not support the requested operation. - */ - EOPNOTSUPP = 64, - - /** - * Value too large to be stored in data type. An operation was - * attempted which would generate a value that is outside the - * range of values that can be represented in the relevant data - * type or that are allowed for a given data item. - */ - EOVERFLOW = 65, - - /** - * Previous owner died. The owner of a robust mutex terminated - * while holding the mutex lock. - */ - EOWNERDEAD = 66, - - /** - * Operation not permitted. An attempt was made to perform an - * operation limited to processes with appropriate privileges or - * to the owner of a file or other resource. - */ - EPERM = 67, - - /** - * Broken pipe. A write was attempted on a socket, pipe, or FIFO - * for which there is no process to read the data. - */ - EPIPE = 68, - - /** - * Protocol error. Some protocol error occurred. This error is - * device-specific, but is generally not related to a - * hardware failure. - */ - EPROTO = 69, - - /** - * Protocol not supported. The protocol is not supported by the - * address family, or the protocol is not supported by - * the implementation. - */ - EPROTONOSUPPORT = 70, - - /** - * Protocol wrong type for socket. The socket type is not - * supported by the protocol. - */ - EPROTOTYPE = 71, - - /** - * Result too large or too small. The result of the function - * is too large (overflow) or too small (underflow) to be - * represented in the available space. - */ - ERANGE = 72, - - /** - * Read-only file system. An attempt was made to modify a file - * or directory on a file system that is read-only. - */ - EROFS = 73, - - /** - * Invalid seek. An attempt was made to access the file offset - * associated with a pipe or FIFO. - */ - ESPIPE = 74, - - /** - * No such process. No process can be found corresponding to that - * specified by the given process ID. - */ - ESRCH = 75, - - /** - * Reserved. - */ - ESTALE = 76, - - /** - * STREAM ioctl() timeout. The timer set for a STREAMS ioctl() call - * has expired. The cause of this error is device-specific and could - * indicate either a hardware or software failure, or a timeout - * value that is too short for the specific operation. The status - * of the ioctl() operation is unspecified. - */ - ETIME = 77, - - /** - * Connection timed out. The connection to a remote machine has - * timed out. - * If the connection timed out during execution of the function that - * reported this error (as opposed to timing out prior to the - * function being called), it is unspecified whether the function - * has completed some or all of the documented behavior associated - * with a successful completion of the function. - * or: - * Operation timed out. The time limit associated with the operation - * was exceeded before the operation completed. - */ - ETIMEDOUT = 78, - - /** - * Text file busy. An attempt was made to execute a pure-procedure - * program that is currently open for writing, or an attempt has - * been made to open for writing a pure-procedure program that - * is being executed. - */ - ETXTBSY = 79, - - /** - * Operation would block. An operation on a socket marked as - * non-blocking has encountered a situation such as no data available - * that otherwise would have caused the function to suspend execution. - */ - EWOULDBLOCK = 80, - - /** - * Improper link. A link to a file on another file system was attempted. - */ - EXDEV = 81, - - __ERRNO_MAX -} KernelErrors; - -#ifdef __cplusplus -extern "C" -{ + +/** + * No Error + */ +#define EOK 0 + +/** + * Argument list too long. The sum of the number of bytes used by the + * new process image's argument list and environment list is greater + * than the system-imposed limit of {ARG_MAX} bytes. + * or: + * Lack of space in an output buffer. + * or: + * Argument is greater than the system-imposed maximum. + */ +#define E2BIG 1 + +/** + * Permission denied. An attempt was made to access a file in a way + * forbidden by its file access permissions. + */ +#define EACCES 2 + +/** + * Address in use. The specified address is in use. + */ +#define EADDRINUSE 3 + +/** + * Address not available. The specified address is not available from + * the local system. + */ +#define EADDRNOTAVAIL 4 + +/** + * Address family not supported. The implementation does not support + * the specified address family, or the specified address is not a + * valid address for the address family of the specified socket. + */ +#define EAFNOSUPPORT 5 + +/** + * Resource temporarily unavailable. This is a temporary condition + * and later calls to the same routine may complete normally. + */ +#define EAGAIN 6 + +/** + * Connection already in progress. A connection request is already in + * progress for the specified socket. + */ +#define EALREADY 7 + +/** + * Bad file descriptor. A file descriptor argument is out of range, + * refers to no open file, or a read (write) request is made to a + * file that is only open for writing (reading). + */ +#define EBADF 8 + +/** + * Bad message. During a read(), getmsg(), getpmsg(), or ioctl() + * I_RECVFD request to a STREAMS device, a message arrived at the + * head of the STREAM that is inappropriate for the function + * receiving the message. + * read() + * Message waiting to be read on a STREAM is not a data message. + * getmsg() or getpmsg() + * A file descriptor was received instead of a control message. + * ioctl() + * Control or data information was received instead of a file + * descriptor when I_RECVFD was specified. + */ +#define EBADMSG 9 + +/** + * Resource busy. An attempt was made to make use of a system + * resource that is not currently available, as it is being + * used by another process in a manner that would have + * conflicted with the request being made by this process. + */ +#define EBUSY 10 + +/** + * Operation canceled. The associated asynchronous operation was + * canceled before completion. + */ +#define ECANCELED 11 + +/** + * No child process. A wait(), waitid(), or waitpid() function was + * executed by a process that had no existing or unwaited-for + * child process. + */ +#define ECHILD 12 + +/** + * Connection aborted. The connection has been aborted. + */ +#define ECONNABORTED 13 + +/** + * Connection refused. An attempt to connect to a socket was refused + * because there was no process listening or because the queue of + * connection requests was full and the underlying protocol does not + * support retransmissions. + */ +#define ECONNREFUSED 14 + +/** + * Connection reset. The connection was forcibly closed by the peer. + */ +#define ECONNRESET 15 + +/** + * Resource deadlock would occur. An attempt was made to lock a system + * resource that would have resulted in a deadlock situation. + */ +#define EDEADLK 16 + +/** + * Destination address required. No bind address was established. + */ +#define EDESTADDRREQ 17 + +/** + * Domain error. An input argument is outside the defined domain of the + * mathematical function (defined in the ISO C standard). + */ +#define EDOM 18 + +/** + * Reserved. + */ +#define EDQUOT 19 + +/** + * File exists. An existing file was mentioned in an inappropriate + * context; for example, as a new link name in the link() function. + */ +#define EEXIST 20 + +/** + * Bad address. The system detected an invalid address in attempting + * to use an argument of a call. The reliable detection of this error + * cannot be guaranteed, and when not detected may result in the + * generation of a signal, indicating an address violation, which is + * sent to the process. + */ +#define EFAULT 21 + +/** + * File too large. The size of a file would exceed the maximum file + * size of an implementation or offset maximum established in the + * corresponding file description. + */ +#define EFBIG 22 + +/** + * Host is unreachable. The destination host cannot be reached + * (probably because the host is down or a remote router cannot + * reach it). + */ +#define EHOSTUNREACH 23 + +/** + * Identifier removed. Returned during XSI interprocess communication + * if an identifier has been removed from the system. + */ +#define EIDRM 24 + +/** + * Illegal byte sequence. A wide-character code has been detected that + * does not correspond to a valid character, or a byte sequence does + * not form a valid wide-character code (defined in the ISO C standard). + */ +#define EILSEQ 25 + +/** + * Operation in progress. This code is used to indicate that an + * asynchronous operation has not yet completed. + * or: + * O_NONBLOCK is set for the socket file descriptor and the connection + * cannot be immediately established. + */ +#define EINPROGRESS 26 + +/** + * Interrupted function call. An asynchronous signal was caught by the + * process during the execution of an interruptible function. If the + * signal handler performs a normal return, the interrupted function + * call may return this condition (see the Base Definitions volume + * of POSIX.1-2017, ). + */ +#define EINTR 27 + +/** + * Invalid argument. Some invalid argument was supplied; for example, + * specifying an undefined signal in a signal() function or a + * kill() function. + */ +#define EINVAL 28 + +/** + * Input/output error. Some physical input or output error has occurred. + * This error may be reported on a subsequent operation on the same + * file descriptor. Any other error-causing operation on the same file + * descriptor may cause the [EIO] error indication to be lost. + */ +#define EIO 29 + +/** + * Socket is connected. The specified socket is already connected. + */ +#define EISCONN 30 + +/** + * Is a directory. An attempt was made to open a directory with write + * mode specified. + */ +#define EISDIR 31 + +/** + * Symbolic link loop. A loop exists in symbolic links encountered + * during pathname resolution. This error may also be returned if + * more than {SYMLOOP_MAX} symbolic links are encountered during + * pathname resolution. + */ +#define ELOOP 32 + +/** + * File descriptor value too large or too many open streams. An + * attempt was made to open a file descriptor with a value greater + * than or equal to {OPEN_MAX}, or an attempt was made to open more + * than the maximum number of streams allowed in the process. + */ +#define EMFILE 33 + +/** + * Too many links. An attempt was made to have the link count of a + * single file exceed {LINK_MAX}. + */ +#define EMLINK 34 + +/** + * Message too large. A message sent on a transport provider was + * larger than an internal message buffer or some other network limit. + * or: + * Inappropriate message buffer length. + */ +#define EMSGSIZE 35 + +/** + * Reserved. + */ +#define EMULTIHOP 36 + +/** + * Filename too long. The length of a pathname exceeds {PATH_MAX} and + * the implementation considers this to be an error, or a pathname + * component is longer than {NAME_MAX}. This error may also occur + * when pathname substitution, as a result of encountering a + * symbolic link during pathname resolution, results in a pathname + * string the size of which exceeds {PATH_MAX}. + */ +#define ENAMETOOLONG 37 + +/** + * Network is down. The local network interface used to reach the + * destination is down. + */ +#define ENETDOWN 38 + +/** + * The connection was aborted by the network. + */ +#define ENETRESET 39 + +/** + * Network unreachable. No route to the network is present. + */ +#define ENETUNREACH 40 + +/** + * Too many files open in system. Too many files are currently open + * in the system. The system has reached its predefined limit for + * simultaneously open files and temporarily cannot accept requests + * to open another one. + */ +#define ENFILE 41 + +/** + * No buffer space available. Insufficient buffer resources were + * available in the system to perform the socket operation. + */ +#define ENOBUFS 42 + +/** + * No message available. No message is available on the STREAM head + * read queue. + */ +#define ENODATA 43 + +/** + * No such device. An attempt was made to apply an inappropriate + * function to a device; for example, trying to read a write-only + * device such as a printer. + */ +#define ENODEV 44 + +/** + * No such file or directory. A component of a specified pathname + * does not exist, or the pathname is an empty string. + */ +#define ENOENT 45 + +/** + * Executable file format error. A request is made to execute a file + * that, although it has appropriate privileges, is not in the + * format required by the implementation for executable files. + */ +#define ENOEXEC 46 + +/** + * No locks available. A system-imposed limit on the number of + * simultaneous file and record locks has been reached and no more + * are currently available. + */ +#define ENOLCK 47 + +/** + * Reserved. + */ +#define ENOLINK 48 + +/** + * Not enough space. The new process image requires more memory than + * is allowed by the hardware or system-imposed memory management + * constraints. + */ +#define ENOMEM 49 + +/** + * No message of the desired type. The message queue does not contain + * a message of the required type during XSI interprocess communication. + */ +#define ENOMSG 50 + +/** + * Protocol not available. The protocol option specified to + * setsockopt() is not supported by the implementation. + */ +#define ENOPROTOOPT 51 + +/** + * No space left on a device. During the write() function on a + * regular file or when extending a directory, there is no free + * space left on the device. + */ +#define ENOSPC 52 + +/** + * No STREAM resources. Insufficient STREAMS memory resources are + * available to perform a STREAMS-related function. This is a + * temporary condition; it may be recovered from if other + * processes release resources. + */ +#define ENOSR 53 + +/** + * Not a STREAM. A STREAM function was attempted on a file descriptor + * that was not associated with a STREAMS device. + */ +#define ENOSTR 54 + +/** + * Functionality not supported. An attempt was made to use optional + * functionality that is not supported in this implementation. + */ +#define ENOSYS 55 + +/** + * Socket not connected. The socket is not connected. + */ +#define ENOTCONN 56 + +/** + * Not a directory. A component of the specified pathname exists, but + * it is not a directory, when a directory was expected; or an + * attempt was made to create a non-directory file, and the specified + * pathname contains at least one non- \ character and ends + * with one or more trailing \ characters. + */ +#define ENOTDIR 57 + +/** + * Directory not empty. A directory other than an empty directory + * was supplied when an empty directory was expected. + */ +#define ENOTEMPTY 58 + +/** + * State not recoverable. The state protected by a robust mutex + * is not recoverable. + */ +#define ENOTRECOVERABLE 59 + +/** + * Not a socket. The file descriptor does not refer to a socket. + */ +#define ENOTSOCK 60 + +/** + * Not supported. The implementation does not support the requested + * feature or value. + */ +#define ENOTSUP 61 + +/** + * Inappropriate I/O control operation. A control function has been + * attempted for a file or special file for which the operation + * is inappropriate. + */ +#define ENOTTY 62 + +/** + * No such device or address. Input or output on a special file + * refers to a device that does not exist, or makes a request + * beyond the capabilities of the device. It may also occur when, + * for example, a tape drive is not on-line. + */ +#define ENXIO 63 + +/** + * Operation not supported on socket. The type of socket (address + * family or protocol) does not support the requested operation. + */ +#define EOPNOTSUPP 64 + +/** + * Value too large to be stored in data type. An operation was + * attempted which would generate a value that is outside the + * range of values that can be represented in the relevant data + * type or that are allowed for a given data item. + */ +#define EOVERFLOW 65 + +/** + * Previous owner died. The owner of a robust mutex terminated + * while holding the mutex lock. + */ +#define EOWNERDEAD 66 + +/** + * Operation not permitted. An attempt was made to perform an + * operation limited to processes with appropriate privileges or + * to the owner of a file or other resource. + */ +#define EPERM 67 + +/** + * Broken pipe. A write was attempted on a socket, pipe, or FIFO + * for which there is no process to read the data. + */ +#define EPIPE 68 + +/** + * Protocol error. Some protocol error occurred. This error is + * device-specific, but is generally not related to a + * hardware failure. + */ +#define EPROTO 69 + +/** + * Protocol not supported. The protocol is not supported by the + * address family, or the protocol is not supported by + * the implementation. + */ +#define EPROTONOSUPPORT 70 + +/** + * Protocol wrong type for socket. The socket type is not + * supported by the protocol. + */ +#define EPROTOTYPE 71 + +/** + * Result too large or too small. The result of the function + * is too large (overflow) or too small (underflow) to be + * represented in the available space. + */ +#define ERANGE 72 + +/** + * Read-only file system. An attempt was made to modify a file + * or directory on a file system that is read-only. + */ +#define EROFS 73 + +/** + * Invalid seek. An attempt was made to access the file offset + * associated with a pipe or FIFO. + */ +#define ESPIPE 74 + +/** + * No such process. No process can be found corresponding to that + * specified by the given process ID. + */ +#define ESRCH 75 + +/** + * Reserved. + */ +#define ESTALE 76 + +/** + * STREAM ioctl() timeout. The timer set for a STREAMS ioctl() call + * has expired. The cause of this error is device-specific and could + * indicate either a hardware or software failure, or a timeout + * value that is too short for the specific operation. The status + * of the ioctl() operation is unspecified. + */ +#define ETIME 77 + +/** + * Connection timed out. The connection to a remote machine has + * timed out. + * If the connection timed out during execution of the function that + * reported this error (as opposed to timing out prior to the + * function being called), it is unspecified whether the function + * has completed some or all of the documented behavior associated + * with a successful completion of the function. + * or: + * Operation timed out. The time limit associated with the operation + * was exceeded before the operation completed. + */ +#define ETIMEDOUT 78 + +/** + * Text file busy. An attempt was made to execute a pure-procedure + * program that is currently open for writing, or an attempt has + * been made to open for writing a pure-procedure program that + * is being executed. + */ +#define ETXTBSY 79 + +/** + * Operation would block. An operation on a socket marked as + * non-blocking has encountered a situation such as no data available + * that otherwise would have caused the function to suspend execution. + */ +#define EWOULDBLOCK 80 + +/** + * Improper link. A link to a file on another file system was attempted. + */ +#define EXDEV 81 + +#ifdef __kernel__ +#define __ERRNO_MAX 82 #endif - int *__errno_location(void) __attribute__((const)); - char *strerror(int errnum); - -#ifdef __cplusplus -} -#endif - -#define errno (*__errno_location()) - #endif // !__FENNIX_API_ERRNO_H__ diff --git a/Drivers/include/syscalls.h b/Drivers/include/syscalls.h index 72a89c7d..df4dcd43 100644 --- a/Drivers/include/syscalls.h +++ b/Drivers/include/syscalls.h @@ -15,8 +15,8 @@ along with Fennix Kernel. If not, see . */ -#ifndef __FENNIX_API_SYSCALLS_LIST_H__ -#define __FENNIX_API_SYSCALLS_LIST_H__ +#ifndef __FENNIX_API_SYSTEM_CALLS_LIST_H__ +#define __FENNIX_API_SYSTEM_CALLS_LIST_H__ #pragma region Syscall Wrappers @@ -1809,4 +1809,4 @@ typedef enum /** @copydoc SYS_UNAME */ #define call_uname(buf) syscall1(SYS_UNAME, (scarg)buf) -#endif // !__FENNIX_API_SYSCALLS_LIST_H__ +#endif // !__FENNIX_API_SYSTEM_CALLS_LIST_H__ diff --git a/Kernel/include/interface/errno.h b/Kernel/include/interface/errno.h index ee601518..e9dfcabd 100644 --- a/Kernel/include/interface/errno.h +++ b/Kernel/include/interface/errno.h @@ -25,581 +25,567 @@ * Full list: * https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/basedefs/errno.h.html */ -typedef enum -{ - /** - * No Error - */ - EOK = 0, - - /** - * Argument list too long. The sum of the number of bytes used by the - * new process image's argument list and environment list is greater - * than the system-imposed limit of {ARG_MAX} bytes. - * or: - * Lack of space in an output buffer. - * or: - * Argument is greater than the system-imposed maximum. - */ - E2BIG = 1, - - /** - * Permission denied. An attempt was made to access a file in a way - * forbidden by its file access permissions. - */ - EACCES = 2, - - /** - * Address in use. The specified address is in use. - */ - EADDRINUSE = 3, - - /** - * Address not available. The specified address is not available from - * the local system. - */ - EADDRNOTAVAIL = 4, - - /** - * Address family not supported. The implementation does not support - * the specified address family, or the specified address is not a - * valid address for the address family of the specified socket. - */ - EAFNOSUPPORT = 5, - - /** - * Resource temporarily unavailable. This is a temporary condition - * and later calls to the same routine may complete normally. - */ - EAGAIN = 6, - - /** - * Connection already in progress. A connection request is already in - * progress for the specified socket. - */ - EALREADY = 7, - - /** - * Bad file descriptor. A file descriptor argument is out of range, - * refers to no open file, or a read (write) request is made to a - * file that is only open for writing (reading). - */ - EBADF = 8, - - /** - * Bad message. During a read(), getmsg(), getpmsg(), or ioctl() - * I_RECVFD request to a STREAMS device, a message arrived at the - * head of the STREAM that is inappropriate for the function - * receiving the message. - * read() - * Message waiting to be read on a STREAM is not a data message. - * getmsg() or getpmsg() - * A file descriptor was received instead of a control message. - * ioctl() - * Control or data information was received instead of a file - * descriptor when I_RECVFD was specified. - */ - EBADMSG = 9, - - /** - * Resource busy. An attempt was made to make use of a system - * resource that is not currently available, as it is being - * used by another process in a manner that would have - * conflicted with the request being made by this process. - */ - EBUSY = 10, - - /** - * Operation canceled. The associated asynchronous operation was - * canceled before completion. - */ - ECANCELED = 11, - - /** - * No child process. A wait(), waitid(), or waitpid() function was - * executed by a process that had no existing or unwaited-for - * child process. - */ - ECHILD = 12, - - /** - * Connection aborted. The connection has been aborted. - */ - ECONNABORTED = 13, - - /** - * Connection refused. An attempt to connect to a socket was refused - * because there was no process listening or because the queue of - * connection requests was full and the underlying protocol does not - * support retransmissions. - */ - ECONNREFUSED = 14, - - /** - * Connection reset. The connection was forcibly closed by the peer. - */ - ECONNRESET = 15, - - /** - * Resource deadlock would occur. An attempt was made to lock a system - * resource that would have resulted in a deadlock situation. - */ - EDEADLK = 16, - - /** - * Destination address required. No bind address was established. - */ - EDESTADDRREQ = 17, - - /** - * Domain error. An input argument is outside the defined domain of the - * mathematical function (defined in the ISO C standard). - */ - EDOM = 18, - - /** - * Reserved. - */ - EDQUOT = 19, - - /** - * File exists. An existing file was mentioned in an inappropriate - * context; for example, as a new link name in the link() function. - */ - EEXIST = 20, - - /** - * Bad address. The system detected an invalid address in attempting - * to use an argument of a call. The reliable detection of this error - * cannot be guaranteed, and when not detected may result in the - * generation of a signal, indicating an address violation, which is - * sent to the process. - */ - EFAULT = 21, - - /** - * File too large. The size of a file would exceed the maximum file - * size of an implementation or offset maximum established in the - * corresponding file description. - */ - EFBIG = 22, - - /** - * Host is unreachable. The destination host cannot be reached - * (probably because the host is down or a remote router cannot - * reach it). - */ - EHOSTUNREACH = 23, - - /** - * Identifier removed. Returned during XSI interprocess communication - * if an identifier has been removed from the system. - */ - EIDRM = 24, - - /** - * Illegal byte sequence. A wide-character code has been detected that - * does not correspond to a valid character, or a byte sequence does - * not form a valid wide-character code (defined in the ISO C standard). - */ - EILSEQ = 25, - - /** - * Operation in progress. This code is used to indicate that an - * asynchronous operation has not yet completed. - * or: - * O_NONBLOCK is set for the socket file descriptor and the connection - * cannot be immediately established. - */ - EINPROGRESS = 26, - - /** - * Interrupted function call. An asynchronous signal was caught by the - * process during the execution of an interruptible function. If the - * signal handler performs a normal return, the interrupted function - * call may return this condition (see the Base Definitions volume - * of POSIX.1-2017, ). - */ - EINTR = 27, - - /** - * Invalid argument. Some invalid argument was supplied; for example, - * specifying an undefined signal in a signal() function or a - * kill() function. - */ - EINVAL = 28, - - /** - * Input/output error. Some physical input or output error has occurred. - * This error may be reported on a subsequent operation on the same - * file descriptor. Any other error-causing operation on the same file - * descriptor may cause the [EIO] error indication to be lost. - */ - EIO = 29, - - /** - * Socket is connected. The specified socket is already connected. - */ - EISCONN = 30, - - /** - * Is a directory. An attempt was made to open a directory with write - * mode specified. - */ - EISDIR = 31, - - /** - * Symbolic link loop. A loop exists in symbolic links encountered - * during pathname resolution. This error may also be returned if - * more than {SYMLOOP_MAX} symbolic links are encountered during - * pathname resolution. - */ - ELOOP = 32, - - /** - * File descriptor value too large or too many open streams. An - * attempt was made to open a file descriptor with a value greater - * than or equal to {OPEN_MAX}, or an attempt was made to open more - * than the maximum number of streams allowed in the process. - */ - EMFILE = 33, - - /** - * Too many links. An attempt was made to have the link count of a - * single file exceed {LINK_MAX}. - */ - EMLINK = 34, - - /** - * Message too large. A message sent on a transport provider was - * larger than an internal message buffer or some other network limit. - * or: - * Inappropriate message buffer length. - */ - EMSGSIZE = 35, - - /** - * Reserved. - */ - EMULTIHOP = 36, - - /** - * Filename too long. The length of a pathname exceeds {PATH_MAX} and - * the implementation considers this to be an error, or a pathname - * component is longer than {NAME_MAX}. This error may also occur - * when pathname substitution, as a result of encountering a - * symbolic link during pathname resolution, results in a pathname - * string the size of which exceeds {PATH_MAX}. - */ - ENAMETOOLONG = 37, - - /** - * Network is down. The local network interface used to reach the - * destination is down. - */ - ENETDOWN = 38, - - /** - * The connection was aborted by the network. - */ - ENETRESET = 39, - - /** - * Network unreachable. No route to the network is present. - */ - ENETUNREACH = 40, - - /** - * Too many files open in system. Too many files are currently open - * in the system. The system has reached its predefined limit for - * simultaneously open files and temporarily cannot accept requests - * to open another one. - */ - ENFILE = 41, - - /** - * No buffer space available. Insufficient buffer resources were - * available in the system to perform the socket operation. - */ - ENOBUFS = 42, - - /** - * No message available. No message is available on the STREAM head - * read queue. - */ - ENODATA = 43, - - /** - * No such device. An attempt was made to apply an inappropriate - * function to a device; for example, trying to read a write-only - * device such as a printer. - */ - ENODEV = 44, - - /** - * No such file or directory. A component of a specified pathname - * does not exist, or the pathname is an empty string. - */ - ENOENT = 45, - - /** - * Executable file format error. A request is made to execute a file - * that, although it has appropriate privileges, is not in the - * format required by the implementation for executable files. - */ - ENOEXEC = 46, - - /** - * No locks available. A system-imposed limit on the number of - * simultaneous file and record locks has been reached and no more - * are currently available. - */ - ENOLCK = 47, - - /** - * Reserved. - */ - ENOLINK = 48, - - /** - * Not enough space. The new process image requires more memory than - * is allowed by the hardware or system-imposed memory management - * constraints. - */ - ENOMEM = 49, - - /** - * No message of the desired type. The message queue does not contain - * a message of the required type during XSI interprocess communication. - */ - ENOMSG = 50, - - /** - * Protocol not available. The protocol option specified to - * setsockopt() is not supported by the implementation. - */ - ENOPROTOOPT = 51, - - /** - * No space left on a device. During the write() function on a - * regular file or when extending a directory, there is no free - * space left on the device. - */ - ENOSPC = 52, - - /** - * No STREAM resources. Insufficient STREAMS memory resources are - * available to perform a STREAMS-related function. This is a - * temporary condition; it may be recovered from if other - * processes release resources. - */ - ENOSR = 53, - - /** - * Not a STREAM. A STREAM function was attempted on a file descriptor - * that was not associated with a STREAMS device. - */ - ENOSTR = 54, - - /** - * Functionality not supported. An attempt was made to use optional - * functionality that is not supported in this implementation. - */ - ENOSYS = 55, - - /** - * Socket not connected. The socket is not connected. - */ - ENOTCONN = 56, - - /** - * Not a directory. A component of the specified pathname exists, but - * it is not a directory, when a directory was expected; or an - * attempt was made to create a non-directory file, and the specified - * pathname contains at least one non- \ character and ends - * with one or more trailing \ characters. - */ - ENOTDIR = 57, - - /** - * Directory not empty. A directory other than an empty directory - * was supplied when an empty directory was expected. - */ - ENOTEMPTY = 58, - - /** - * State not recoverable. The state protected by a robust mutex - * is not recoverable. - */ - ENOTRECOVERABLE = 59, - - /** - * Not a socket. The file descriptor does not refer to a socket. - */ - ENOTSOCK = 60, - - /** - * Not supported. The implementation does not support the requested - * feature or value. - */ - ENOTSUP = 61, - - /** - * Inappropriate I/O control operation. A control function has been - * attempted for a file or special file for which the operation - * is inappropriate. - */ - ENOTTY = 62, - - /** - * No such device or address. Input or output on a special file - * refers to a device that does not exist, or makes a request - * beyond the capabilities of the device. It may also occur when, - * for example, a tape drive is not on-line. - */ - ENXIO = 63, - - /** - * Operation not supported on socket. The type of socket (address - * family or protocol) does not support the requested operation. - */ - EOPNOTSUPP = 64, - - /** - * Value too large to be stored in data type. An operation was - * attempted which would generate a value that is outside the - * range of values that can be represented in the relevant data - * type or that are allowed for a given data item. - */ - EOVERFLOW = 65, - - /** - * Previous owner died. The owner of a robust mutex terminated - * while holding the mutex lock. - */ - EOWNERDEAD = 66, - - /** - * Operation not permitted. An attempt was made to perform an - * operation limited to processes with appropriate privileges or - * to the owner of a file or other resource. - */ - EPERM = 67, - - /** - * Broken pipe. A write was attempted on a socket, pipe, or FIFO - * for which there is no process to read the data. - */ - EPIPE = 68, - - /** - * Protocol error. Some protocol error occurred. This error is - * device-specific, but is generally not related to a - * hardware failure. - */ - EPROTO = 69, - - /** - * Protocol not supported. The protocol is not supported by the - * address family, or the protocol is not supported by - * the implementation. - */ - EPROTONOSUPPORT = 70, - - /** - * Protocol wrong type for socket. The socket type is not - * supported by the protocol. - */ - EPROTOTYPE = 71, - - /** - * Result too large or too small. The result of the function - * is too large (overflow) or too small (underflow) to be - * represented in the available space. - */ - ERANGE = 72, - - /** - * Read-only file system. An attempt was made to modify a file - * or directory on a file system that is read-only. - */ - EROFS = 73, - - /** - * Invalid seek. An attempt was made to access the file offset - * associated with a pipe or FIFO. - */ - ESPIPE = 74, - - /** - * No such process. No process can be found corresponding to that - * specified by the given process ID. - */ - ESRCH = 75, - - /** - * Reserved. - */ - ESTALE = 76, - - /** - * STREAM ioctl() timeout. The timer set for a STREAMS ioctl() call - * has expired. The cause of this error is device-specific and could - * indicate either a hardware or software failure, or a timeout - * value that is too short for the specific operation. The status - * of the ioctl() operation is unspecified. - */ - ETIME = 77, - - /** - * Connection timed out. The connection to a remote machine has - * timed out. - * If the connection timed out during execution of the function that - * reported this error (as opposed to timing out prior to the - * function being called), it is unspecified whether the function - * has completed some or all of the documented behavior associated - * with a successful completion of the function. - * or: - * Operation timed out. The time limit associated with the operation - * was exceeded before the operation completed. - */ - ETIMEDOUT = 78, - - /** - * Text file busy. An attempt was made to execute a pure-procedure - * program that is currently open for writing, or an attempt has - * been made to open for writing a pure-procedure program that - * is being executed. - */ - ETXTBSY = 79, - - /** - * Operation would block. An operation on a socket marked as - * non-blocking has encountered a situation such as no data available - * that otherwise would have caused the function to suspend execution. - */ - EWOULDBLOCK = 80, - - /** - * Improper link. A link to a file on another file system was attempted. - */ - EXDEV = 81, - - __ERRNO_MAX -} KernelErrors; - -#ifdef __cplusplus -extern "C" -{ + +/** + * No Error + */ +#define EOK 0 + +/** + * Argument list too long. The sum of the number of bytes used by the + * new process image's argument list and environment list is greater + * than the system-imposed limit of {ARG_MAX} bytes. + * or: + * Lack of space in an output buffer. + * or: + * Argument is greater than the system-imposed maximum. + */ +#define E2BIG 1 + +/** + * Permission denied. An attempt was made to access a file in a way + * forbidden by its file access permissions. + */ +#define EACCES 2 + +/** + * Address in use. The specified address is in use. + */ +#define EADDRINUSE 3 + +/** + * Address not available. The specified address is not available from + * the local system. + */ +#define EADDRNOTAVAIL 4 + +/** + * Address family not supported. The implementation does not support + * the specified address family, or the specified address is not a + * valid address for the address family of the specified socket. + */ +#define EAFNOSUPPORT 5 + +/** + * Resource temporarily unavailable. This is a temporary condition + * and later calls to the same routine may complete normally. + */ +#define EAGAIN 6 + +/** + * Connection already in progress. A connection request is already in + * progress for the specified socket. + */ +#define EALREADY 7 + +/** + * Bad file descriptor. A file descriptor argument is out of range, + * refers to no open file, or a read (write) request is made to a + * file that is only open for writing (reading). + */ +#define EBADF 8 + +/** + * Bad message. During a read(), getmsg(), getpmsg(), or ioctl() + * I_RECVFD request to a STREAMS device, a message arrived at the + * head of the STREAM that is inappropriate for the function + * receiving the message. + * read() + * Message waiting to be read on a STREAM is not a data message. + * getmsg() or getpmsg() + * A file descriptor was received instead of a control message. + * ioctl() + * Control or data information was received instead of a file + * descriptor when I_RECVFD was specified. + */ +#define EBADMSG 9 + +/** + * Resource busy. An attempt was made to make use of a system + * resource that is not currently available, as it is being + * used by another process in a manner that would have + * conflicted with the request being made by this process. + */ +#define EBUSY 10 + +/** + * Operation canceled. The associated asynchronous operation was + * canceled before completion. + */ +#define ECANCELED 11 + +/** + * No child process. A wait(), waitid(), or waitpid() function was + * executed by a process that had no existing or unwaited-for + * child process. + */ +#define ECHILD 12 + +/** + * Connection aborted. The connection has been aborted. + */ +#define ECONNABORTED 13 + +/** + * Connection refused. An attempt to connect to a socket was refused + * because there was no process listening or because the queue of + * connection requests was full and the underlying protocol does not + * support retransmissions. + */ +#define ECONNREFUSED 14 + +/** + * Connection reset. The connection was forcibly closed by the peer. + */ +#define ECONNRESET 15 + +/** + * Resource deadlock would occur. An attempt was made to lock a system + * resource that would have resulted in a deadlock situation. + */ +#define EDEADLK 16 + +/** + * Destination address required. No bind address was established. + */ +#define EDESTADDRREQ 17 + +/** + * Domain error. An input argument is outside the defined domain of the + * mathematical function (defined in the ISO C standard). + */ +#define EDOM 18 + +/** + * Reserved. + */ +#define EDQUOT 19 + +/** + * File exists. An existing file was mentioned in an inappropriate + * context; for example, as a new link name in the link() function. + */ +#define EEXIST 20 + +/** + * Bad address. The system detected an invalid address in attempting + * to use an argument of a call. The reliable detection of this error + * cannot be guaranteed, and when not detected may result in the + * generation of a signal, indicating an address violation, which is + * sent to the process. + */ +#define EFAULT 21 + +/** + * File too large. The size of a file would exceed the maximum file + * size of an implementation or offset maximum established in the + * corresponding file description. + */ +#define EFBIG 22 + +/** + * Host is unreachable. The destination host cannot be reached + * (probably because the host is down or a remote router cannot + * reach it). + */ +#define EHOSTUNREACH 23 + +/** + * Identifier removed. Returned during XSI interprocess communication + * if an identifier has been removed from the system. + */ +#define EIDRM 24 + +/** + * Illegal byte sequence. A wide-character code has been detected that + * does not correspond to a valid character, or a byte sequence does + * not form a valid wide-character code (defined in the ISO C standard). + */ +#define EILSEQ 25 + +/** + * Operation in progress. This code is used to indicate that an + * asynchronous operation has not yet completed. + * or: + * O_NONBLOCK is set for the socket file descriptor and the connection + * cannot be immediately established. + */ +#define EINPROGRESS 26 + +/** + * Interrupted function call. An asynchronous signal was caught by the + * process during the execution of an interruptible function. If the + * signal handler performs a normal return, the interrupted function + * call may return this condition (see the Base Definitions volume + * of POSIX.1-2017, ). + */ +#define EINTR 27 + +/** + * Invalid argument. Some invalid argument was supplied; for example, + * specifying an undefined signal in a signal() function or a + * kill() function. + */ +#define EINVAL 28 + +/** + * Input/output error. Some physical input or output error has occurred. + * This error may be reported on a subsequent operation on the same + * file descriptor. Any other error-causing operation on the same file + * descriptor may cause the [EIO] error indication to be lost. + */ +#define EIO 29 + +/** + * Socket is connected. The specified socket is already connected. + */ +#define EISCONN 30 + +/** + * Is a directory. An attempt was made to open a directory with write + * mode specified. + */ +#define EISDIR 31 + +/** + * Symbolic link loop. A loop exists in symbolic links encountered + * during pathname resolution. This error may also be returned if + * more than {SYMLOOP_MAX} symbolic links are encountered during + * pathname resolution. + */ +#define ELOOP 32 + +/** + * File descriptor value too large or too many open streams. An + * attempt was made to open a file descriptor with a value greater + * than or equal to {OPEN_MAX}, or an attempt was made to open more + * than the maximum number of streams allowed in the process. + */ +#define EMFILE 33 + +/** + * Too many links. An attempt was made to have the link count of a + * single file exceed {LINK_MAX}. + */ +#define EMLINK 34 + +/** + * Message too large. A message sent on a transport provider was + * larger than an internal message buffer or some other network limit. + * or: + * Inappropriate message buffer length. + */ +#define EMSGSIZE 35 + +/** + * Reserved. + */ +#define EMULTIHOP 36 + +/** + * Filename too long. The length of a pathname exceeds {PATH_MAX} and + * the implementation considers this to be an error, or a pathname + * component is longer than {NAME_MAX}. This error may also occur + * when pathname substitution, as a result of encountering a + * symbolic link during pathname resolution, results in a pathname + * string the size of which exceeds {PATH_MAX}. + */ +#define ENAMETOOLONG 37 + +/** + * Network is down. The local network interface used to reach the + * destination is down. + */ +#define ENETDOWN 38 + +/** + * The connection was aborted by the network. + */ +#define ENETRESET 39 + +/** + * Network unreachable. No route to the network is present. + */ +#define ENETUNREACH 40 + +/** + * Too many files open in system. Too many files are currently open + * in the system. The system has reached its predefined limit for + * simultaneously open files and temporarily cannot accept requests + * to open another one. + */ +#define ENFILE 41 + +/** + * No buffer space available. Insufficient buffer resources were + * available in the system to perform the socket operation. + */ +#define ENOBUFS 42 + +/** + * No message available. No message is available on the STREAM head + * read queue. + */ +#define ENODATA 43 + +/** + * No such device. An attempt was made to apply an inappropriate + * function to a device; for example, trying to read a write-only + * device such as a printer. + */ +#define ENODEV 44 + +/** + * No such file or directory. A component of a specified pathname + * does not exist, or the pathname is an empty string. + */ +#define ENOENT 45 + +/** + * Executable file format error. A request is made to execute a file + * that, although it has appropriate privileges, is not in the + * format required by the implementation for executable files. + */ +#define ENOEXEC 46 + +/** + * No locks available. A system-imposed limit on the number of + * simultaneous file and record locks has been reached and no more + * are currently available. + */ +#define ENOLCK 47 + +/** + * Reserved. + */ +#define ENOLINK 48 + +/** + * Not enough space. The new process image requires more memory than + * is allowed by the hardware or system-imposed memory management + * constraints. + */ +#define ENOMEM 49 + +/** + * No message of the desired type. The message queue does not contain + * a message of the required type during XSI interprocess communication. + */ +#define ENOMSG 50 + +/** + * Protocol not available. The protocol option specified to + * setsockopt() is not supported by the implementation. + */ +#define ENOPROTOOPT 51 + +/** + * No space left on a device. During the write() function on a + * regular file or when extending a directory, there is no free + * space left on the device. + */ +#define ENOSPC 52 + +/** + * No STREAM resources. Insufficient STREAMS memory resources are + * available to perform a STREAMS-related function. This is a + * temporary condition; it may be recovered from if other + * processes release resources. + */ +#define ENOSR 53 + +/** + * Not a STREAM. A STREAM function was attempted on a file descriptor + * that was not associated with a STREAMS device. + */ +#define ENOSTR 54 + +/** + * Functionality not supported. An attempt was made to use optional + * functionality that is not supported in this implementation. + */ +#define ENOSYS 55 + +/** + * Socket not connected. The socket is not connected. + */ +#define ENOTCONN 56 + +/** + * Not a directory. A component of the specified pathname exists, but + * it is not a directory, when a directory was expected; or an + * attempt was made to create a non-directory file, and the specified + * pathname contains at least one non- \ character and ends + * with one or more trailing \ characters. + */ +#define ENOTDIR 57 + +/** + * Directory not empty. A directory other than an empty directory + * was supplied when an empty directory was expected. + */ +#define ENOTEMPTY 58 + +/** + * State not recoverable. The state protected by a robust mutex + * is not recoverable. + */ +#define ENOTRECOVERABLE 59 + +/** + * Not a socket. The file descriptor does not refer to a socket. + */ +#define ENOTSOCK 60 + +/** + * Not supported. The implementation does not support the requested + * feature or value. + */ +#define ENOTSUP 61 + +/** + * Inappropriate I/O control operation. A control function has been + * attempted for a file or special file for which the operation + * is inappropriate. + */ +#define ENOTTY 62 + +/** + * No such device or address. Input or output on a special file + * refers to a device that does not exist, or makes a request + * beyond the capabilities of the device. It may also occur when, + * for example, a tape drive is not on-line. + */ +#define ENXIO 63 + +/** + * Operation not supported on socket. The type of socket (address + * family or protocol) does not support the requested operation. + */ +#define EOPNOTSUPP 64 + +/** + * Value too large to be stored in data type. An operation was + * attempted which would generate a value that is outside the + * range of values that can be represented in the relevant data + * type or that are allowed for a given data item. + */ +#define EOVERFLOW 65 + +/** + * Previous owner died. The owner of a robust mutex terminated + * while holding the mutex lock. + */ +#define EOWNERDEAD 66 + +/** + * Operation not permitted. An attempt was made to perform an + * operation limited to processes with appropriate privileges or + * to the owner of a file or other resource. + */ +#define EPERM 67 + +/** + * Broken pipe. A write was attempted on a socket, pipe, or FIFO + * for which there is no process to read the data. + */ +#define EPIPE 68 + +/** + * Protocol error. Some protocol error occurred. This error is + * device-specific, but is generally not related to a + * hardware failure. + */ +#define EPROTO 69 + +/** + * Protocol not supported. The protocol is not supported by the + * address family, or the protocol is not supported by + * the implementation. + */ +#define EPROTONOSUPPORT 70 + +/** + * Protocol wrong type for socket. The socket type is not + * supported by the protocol. + */ +#define EPROTOTYPE 71 + +/** + * Result too large or too small. The result of the function + * is too large (overflow) or too small (underflow) to be + * represented in the available space. + */ +#define ERANGE 72 + +/** + * Read-only file system. An attempt was made to modify a file + * or directory on a file system that is read-only. + */ +#define EROFS 73 + +/** + * Invalid seek. An attempt was made to access the file offset + * associated with a pipe or FIFO. + */ +#define ESPIPE 74 + +/** + * No such process. No process can be found corresponding to that + * specified by the given process ID. + */ +#define ESRCH 75 + +/** + * Reserved. + */ +#define ESTALE 76 + +/** + * STREAM ioctl() timeout. The timer set for a STREAMS ioctl() call + * has expired. The cause of this error is device-specific and could + * indicate either a hardware or software failure, or a timeout + * value that is too short for the specific operation. The status + * of the ioctl() operation is unspecified. + */ +#define ETIME 77 + +/** + * Connection timed out. The connection to a remote machine has + * timed out. + * If the connection timed out during execution of the function that + * reported this error (as opposed to timing out prior to the + * function being called), it is unspecified whether the function + * has completed some or all of the documented behavior associated + * with a successful completion of the function. + * or: + * Operation timed out. The time limit associated with the operation + * was exceeded before the operation completed. + */ +#define ETIMEDOUT 78 + +/** + * Text file busy. An attempt was made to execute a pure-procedure + * program that is currently open for writing, or an attempt has + * been made to open for writing a pure-procedure program that + * is being executed. + */ +#define ETXTBSY 79 + +/** + * Operation would block. An operation on a socket marked as + * non-blocking has encountered a situation such as no data available + * that otherwise would have caused the function to suspend execution. + */ +#define EWOULDBLOCK 80 + +/** + * Improper link. A link to a file on another file system was attempted. + */ +#define EXDEV 81 + +#ifdef __kernel__ +#define __ERRNO_MAX 82 #endif - int *__errno_location(void) __attribute__((const)); - char *strerror(int errnum); - -#ifdef __cplusplus -} -#endif - -#define errno (*__errno_location()) - #endif // !__FENNIX_API_ERRNO_H__ diff --git a/Kernel/include/interface/syscalls.h b/Kernel/include/interface/syscalls.h index 72a89c7d..df4dcd43 100644 --- a/Kernel/include/interface/syscalls.h +++ b/Kernel/include/interface/syscalls.h @@ -15,8 +15,8 @@ along with Fennix Kernel. If not, see . */ -#ifndef __FENNIX_API_SYSCALLS_LIST_H__ -#define __FENNIX_API_SYSCALLS_LIST_H__ +#ifndef __FENNIX_API_SYSTEM_CALLS_LIST_H__ +#define __FENNIX_API_SYSTEM_CALLS_LIST_H__ #pragma region Syscall Wrappers @@ -1809,4 +1809,4 @@ typedef enum /** @copydoc SYS_UNAME */ #define call_uname(buf) syscall1(SYS_UNAME, (scarg)buf) -#endif // !__FENNIX_API_SYSCALLS_LIST_H__ +#endif // !__FENNIX_API_SYSTEM_CALLS_LIST_H__ diff --git a/Kernel/include_std/errno.h b/Kernel/include_std/errno.h index 6395b847..82ca04dd 100644 --- a/Kernel/include_std/errno.h +++ b/Kernel/include_std/errno.h @@ -20,4 +20,18 @@ #include +#ifdef __cplusplus +extern "C" +{ +#endif + + int *__errno_location(void) __attribute__((const)); + char *strerror(int errnum); + +#ifdef __cplusplus +} +#endif + +#define errno (*__errno_location()) + #endif // !__FENNIX_KERNEL_STD_ERRNO_H__ diff --git a/Userspace/.vscode/settings.json b/Userspace/.vscode/settings.json index d0a212b6..3c73e302 100644 --- a/Userspace/.vscode/settings.json +++ b/Userspace/.vscode/settings.json @@ -1,5 +1,6 @@ { "git.openRepositoryInParentFolders": "always", "git.alwaysSignOff": true, - "git.defaultBranchName": "master" -} \ No newline at end of file + "git.defaultBranchName": "master", + "cmake.ignoreCMakeListsMissing": true +} diff --git a/Userspace/Fennix C Library.code-workspace b/Userspace/Fennix C Library.code-workspace new file mode 100644 index 00000000..5d7e7795 --- /dev/null +++ b/Userspace/Fennix C Library.code-workspace @@ -0,0 +1,18 @@ +{ + "folders": [ + { + "path": "./libc" + } + ], + "settings": { + "terminal.integrated.cwd": "../../", + "debug.allowBreakpointsEverywhere": true, + "git.alwaysSignOff": true, + "git.defaultBranchName": "master", + "git.openRepositoryInParentFolders": "always", + "C_Cpp.autoAddFileAssociations": false, + "conventionalCommits.scopes": [ + "userspace/libc" + ] + } +} diff --git a/Userspace/Fennix Core Utilities.code-workspace b/Userspace/Fennix Core Utilities.code-workspace new file mode 100644 index 00000000..5183e0ad --- /dev/null +++ b/Userspace/Fennix Core Utilities.code-workspace @@ -0,0 +1,18 @@ +{ + "folders": [ + { + "path": "./coreutils" + } + ], + "settings": { + "terminal.integrated.cwd": "../../", + "debug.allowBreakpointsEverywhere": true, + "git.alwaysSignOff": true, + "git.defaultBranchName": "master", + "git.openRepositoryInParentFolders": "always", + "C_Cpp.autoAddFileAssociations": false, + "conventionalCommits.scopes": [ + "userspace/coreutils" + ] + } +} diff --git a/Userspace/Makefile b/Userspace/Makefile index bfe84f86..106a3fd0 100644 --- a/Userspace/Makefile +++ b/Userspace/Makefile @@ -35,7 +35,7 @@ create_out: mkdir -p out/usr/share/doc mkdir -p out/usr/share/info mkdir -p out/usr/include - cp $(WORKSPACE_DIR)/../Kernel/include/interface/* $(WORKSPACE_DIR)/out/include/fennix/ + cp $(WORKSPACE_DIR)/../Kernel/include/interface/* $(WORKSPACE_DIR)/out/include/fennix/ build_coreutils: mkdir -p cache/coreutils @@ -49,8 +49,23 @@ build_coreutils: make -j$(shell nproc) && \ make install +build_libc: + cp -f $(WORKSPACE_DIR)/../Kernel/include/interface/errno.h $(WORKSPACE_DIR)/libc/abis/fennix/generic/bits/errno.h + cp -f $(WORKSPACE_DIR)/../Kernel/include/interface/syscalls.h $(WORKSPACE_DIR)/libc/abis/fennix/generic/bits/syscalls.h + mkdir -p cache/libc + cd cache/libc && \ + cmake $(WORKSPACE_DIR)/libc \ + -DCMAKE_INSTALL_PREFIX:PATH=$(WORKSPACE_DIR)/out \ + -DCMAKE_SYSROOT=$(WORKSPACE_DIR)/out \ + -DCMAKE_C_STANDARD_INCLUDE_DIRECTORIES=$(WORKSPACE_DIR)/out/include \ + -DTARGET_OS=fennix \ + -DTARGET_ARCH=$(OSARCH) \ + && \ + make -j$(shell nproc) && \ + make install + build: create_out - make -C libc build + $(MAKE) build_libc make -C libs build $(MAKE) build_coreutils make -C apps build @@ -62,6 +77,5 @@ clean: rm -rf out cache mkdir -p cache touch cache/.gitkeep - make -C libc clean make -C libs clean make -C apps clean diff --git a/Userspace/libc/.gitignore b/Userspace/libc/.gitignore new file mode 100644 index 00000000..378eac25 --- /dev/null +++ b/Userspace/libc/.gitignore @@ -0,0 +1 @@ +build diff --git a/Userspace/libc/.vscode/c_boilerplates.code-snippets b/Userspace/libc/.vscode/c_boilerplates.code-snippets new file mode 100644 index 00000000..48892733 --- /dev/null +++ b/Userspace/libc/.vscode/c_boilerplates.code-snippets @@ -0,0 +1,27 @@ +{ + "C Library License": { + "isFileTemplate": true, + "prefix": [ + "license", + ], + "body": [ + "/*", + "\tThis file is part of Fennix C Library.", + "", + "\tFennix C Library is free software: you can redistribute it and/or", + "\tmodify it under the terms of the GNU General Public License as", + "\tpublished by the Free Software Foundation, either version 3 of", + "\tthe License, or (at your option) any later version.", + "", + "\tFennix C Library is distributed in the hope that it will be useful,", + "\tbut WITHOUT ANY WARRANTY; without even the implied warranty of", + "\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the", + "\tGNU General Public License for more details.", + "", + "\tYou should have received a copy of the GNU General Public License", + "\talong with Fennix C Library. If not, see .", + "*/" + ], + "description": "Create libc license." + } +} diff --git a/Userspace/libc/CMakeLists.txt b/Userspace/libc/CMakeLists.txt new file mode 100644 index 00000000..5d6fdf9e --- /dev/null +++ b/Userspace/libc/CMakeLists.txt @@ -0,0 +1,104 @@ +cmake_minimum_required(VERSION 3.10) +set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) +project(FennixCLibrary VERSION 1.0.0) + +if(NOT DEFINED ENV{WORKSPACE_DIR}) + set(STANDALONE_BUILD ON) + message(STATUS "Compiling standalone") + set(CMAKE_INSTALL_PREFIX "/usr") +else() + set(STANDALONE_BUILD OFF) + set(CMAKE_INSTALL_PREFIX "$ENV{WORKSPACE_DIR}/out") + message(STATUS "Compiling within workspace") + try_compile( + WORKSPACE_TEST + ${CMAKE_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/workspace_test.c + CMAKE_FLAGS "-DCMAKE_C_COMPILER=$ENV{CC} -DCMAKE_CXX_COMPILER=$ENV{CXX} -DCMAKE_ASM_COMPILER=$ENV{AS} -DCMAKE_AR=$ENV{AR} -DCMAKE_LINKER=$ENV{LD}" + OUTPUT_VARIABLE OUTPUT) + if(NOT WORKSPACE_TEST) + message(FATAL_ERROR "Workspace test failed: ${OUTPUT}") + else() + message(STATUS "Workspace test passed") + endif() +endif() + +if(NOT DEFINED TARGET_OS) + if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") + set(TARGET_OS "linux") + elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Fennix") + set(TARGET_OS "fennix") + else() + message(FATAL_ERROR "Unsupported OS: ${CMAKE_SYSTEM_NAME}") + endif() +endif() + +if(NOT DEFINED TARGET_ARCH) + set(TARGET_ARCH ${CMAKE_SYSTEM_PROCESSOR}) +endif() + +message(STATUS "Building for ${TARGET_OS}/${TARGET_ARCH}") + +if(DEFINED ENV{CC}) + set(CMAKE_C_COMPILER "$ENV{CC}") +endif() +if(DEFINED ENV{CXX}) + set(CMAKE_CXX_COMPILER "$ENV{CXX}") +endif() +if(DEFINED ENV{AS}) + set(CMAKE_ASM_COMPILER "$ENV{AS}") +endif() +if(DEFINED ENV{AR}) + set(CMAKE_AR "$ENV{AR}") +endif() +if(DEFINED ENV{LD}) + set(CMAKE_LINKER "$ENV{LD}") +endif() + +if(DEFINED ENV{DEBUG} AND "$ENV{DEBUG}" STREQUAL "1") + set(CMAKE_C_FLAGS "-ggdb3 -O0 -DDEBUG") +else() + set(CMAKE_C_FLAGS "-O2") +endif() + +set(SYSDEPS_DIR ${CMAKE_SOURCE_DIR}/sysdeps) +set(ABIS_DIR ${CMAKE_SOURCE_DIR}/abis) + +set(SYSDEPS_GENERIC ${SYSDEPS_DIR}/${TARGET_OS}/generic) +set(SYSDEPS_PATH ${SYSDEPS_DIR}/${TARGET_OS}/${TARGET_ARCH}) +set(ABIS_GENERIC ${ABIS_DIR}/${TARGET_OS}/generic) +set(ABIS_PATH ${ABIS_DIR}/${TARGET_OS}/${TARGET_ARCH}) + +if(NOT EXISTS ${SYSDEPS_PATH} AND NOT EXISTS ${SYSDEPS_GENERIC}) + message(FATAL_ERROR "Missing sysdeps for ${TARGET_OS}: ${SYSDEPS_PATH} or ${SYSDEPS_GENERIC}") +endif() + +if(NOT EXISTS ${ABIS_PATH} AND NOT EXISTS ${ABIS_GENERIC}) + message(FATAL_ERROR "Missing abis for ${TARGET_OS}: ${ABIS_PATH} or ${ABIS_GENERIC}") +endif() + +message(STATUS "Using sysdeps from: ${SYSDEPS_GENERIC} and ${SYSDEPS_PATH}") +message(STATUS "Using abis from: ${ABIS_GENERIC} and ${ABIS_PATH}") + +include_directories(${ABIS_GENERIC} ${ABIS_PATH}) +include_directories(${CMAKE_SOURCE_DIR}/include) + +add_subdirectory(runtime) +add_subdirectory(interpreter) +add_subdirectory(src) +add_subdirectory(libs) + +install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ + DESTINATION include + FILES_MATCHING + PATTERN "*") + +install(DIRECTORY ${ABIS_GENERIC}/ + DESTINATION ${CMAKE_INSTALL_PREFIX}/include/ + FILES_MATCHING + PATTERN "*") + +install(DIRECTORY ${ABIS_PATH}/ + DESTINATION ${CMAKE_INSTALL_PREFIX}/include/ + FILES_MATCHING + PATTERN "*") diff --git a/Userspace/libc/Makefile b/Userspace/libc/Makefile deleted file mode 100644 index f2654b8c..00000000 --- a/Userspace/libc/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -build: - cp -f $(WORKSPACE_DIR)/../Kernel/include/interface/errno.h $(CURDIR)/include/errno.h - cp -f $(WORKSPACE_DIR)/../Kernel/include/interface/syscalls.h $(CURDIR)/include/fennix/syscalls.h - cp -a $(CURDIR)/include/. $(WORKSPACE_DIR)/out/include - make -C interpreter build - make -C runtime build - make -C src build - -clean: - make -C interpreter clean - make -C runtime clean - make -C src clean diff --git a/Userspace/libc/abis/fennix/generic/bits/errno.h b/Userspace/libc/abis/fennix/generic/bits/errno.h new file mode 100644 index 00000000..e9dfcabd --- /dev/null +++ b/Userspace/libc/abis/fennix/generic/bits/errno.h @@ -0,0 +1,591 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#ifndef __FENNIX_API_ERRNO_H__ +#define __FENNIX_API_ERRNO_H__ + +/** + * The documentation for these error codes are from: + * https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html + * + * Full list: + * https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/basedefs/errno.h.html + */ + +/** + * No Error + */ +#define EOK 0 + +/** + * Argument list too long. The sum of the number of bytes used by the + * new process image's argument list and environment list is greater + * than the system-imposed limit of {ARG_MAX} bytes. + * or: + * Lack of space in an output buffer. + * or: + * Argument is greater than the system-imposed maximum. + */ +#define E2BIG 1 + +/** + * Permission denied. An attempt was made to access a file in a way + * forbidden by its file access permissions. + */ +#define EACCES 2 + +/** + * Address in use. The specified address is in use. + */ +#define EADDRINUSE 3 + +/** + * Address not available. The specified address is not available from + * the local system. + */ +#define EADDRNOTAVAIL 4 + +/** + * Address family not supported. The implementation does not support + * the specified address family, or the specified address is not a + * valid address for the address family of the specified socket. + */ +#define EAFNOSUPPORT 5 + +/** + * Resource temporarily unavailable. This is a temporary condition + * and later calls to the same routine may complete normally. + */ +#define EAGAIN 6 + +/** + * Connection already in progress. A connection request is already in + * progress for the specified socket. + */ +#define EALREADY 7 + +/** + * Bad file descriptor. A file descriptor argument is out of range, + * refers to no open file, or a read (write) request is made to a + * file that is only open for writing (reading). + */ +#define EBADF 8 + +/** + * Bad message. During a read(), getmsg(), getpmsg(), or ioctl() + * I_RECVFD request to a STREAMS device, a message arrived at the + * head of the STREAM that is inappropriate for the function + * receiving the message. + * read() + * Message waiting to be read on a STREAM is not a data message. + * getmsg() or getpmsg() + * A file descriptor was received instead of a control message. + * ioctl() + * Control or data information was received instead of a file + * descriptor when I_RECVFD was specified. + */ +#define EBADMSG 9 + +/** + * Resource busy. An attempt was made to make use of a system + * resource that is not currently available, as it is being + * used by another process in a manner that would have + * conflicted with the request being made by this process. + */ +#define EBUSY 10 + +/** + * Operation canceled. The associated asynchronous operation was + * canceled before completion. + */ +#define ECANCELED 11 + +/** + * No child process. A wait(), waitid(), or waitpid() function was + * executed by a process that had no existing or unwaited-for + * child process. + */ +#define ECHILD 12 + +/** + * Connection aborted. The connection has been aborted. + */ +#define ECONNABORTED 13 + +/** + * Connection refused. An attempt to connect to a socket was refused + * because there was no process listening or because the queue of + * connection requests was full and the underlying protocol does not + * support retransmissions. + */ +#define ECONNREFUSED 14 + +/** + * Connection reset. The connection was forcibly closed by the peer. + */ +#define ECONNRESET 15 + +/** + * Resource deadlock would occur. An attempt was made to lock a system + * resource that would have resulted in a deadlock situation. + */ +#define EDEADLK 16 + +/** + * Destination address required. No bind address was established. + */ +#define EDESTADDRREQ 17 + +/** + * Domain error. An input argument is outside the defined domain of the + * mathematical function (defined in the ISO C standard). + */ +#define EDOM 18 + +/** + * Reserved. + */ +#define EDQUOT 19 + +/** + * File exists. An existing file was mentioned in an inappropriate + * context; for example, as a new link name in the link() function. + */ +#define EEXIST 20 + +/** + * Bad address. The system detected an invalid address in attempting + * to use an argument of a call. The reliable detection of this error + * cannot be guaranteed, and when not detected may result in the + * generation of a signal, indicating an address violation, which is + * sent to the process. + */ +#define EFAULT 21 + +/** + * File too large. The size of a file would exceed the maximum file + * size of an implementation or offset maximum established in the + * corresponding file description. + */ +#define EFBIG 22 + +/** + * Host is unreachable. The destination host cannot be reached + * (probably because the host is down or a remote router cannot + * reach it). + */ +#define EHOSTUNREACH 23 + +/** + * Identifier removed. Returned during XSI interprocess communication + * if an identifier has been removed from the system. + */ +#define EIDRM 24 + +/** + * Illegal byte sequence. A wide-character code has been detected that + * does not correspond to a valid character, or a byte sequence does + * not form a valid wide-character code (defined in the ISO C standard). + */ +#define EILSEQ 25 + +/** + * Operation in progress. This code is used to indicate that an + * asynchronous operation has not yet completed. + * or: + * O_NONBLOCK is set for the socket file descriptor and the connection + * cannot be immediately established. + */ +#define EINPROGRESS 26 + +/** + * Interrupted function call. An asynchronous signal was caught by the + * process during the execution of an interruptible function. If the + * signal handler performs a normal return, the interrupted function + * call may return this condition (see the Base Definitions volume + * of POSIX.1-2017, ). + */ +#define EINTR 27 + +/** + * Invalid argument. Some invalid argument was supplied; for example, + * specifying an undefined signal in a signal() function or a + * kill() function. + */ +#define EINVAL 28 + +/** + * Input/output error. Some physical input or output error has occurred. + * This error may be reported on a subsequent operation on the same + * file descriptor. Any other error-causing operation on the same file + * descriptor may cause the [EIO] error indication to be lost. + */ +#define EIO 29 + +/** + * Socket is connected. The specified socket is already connected. + */ +#define EISCONN 30 + +/** + * Is a directory. An attempt was made to open a directory with write + * mode specified. + */ +#define EISDIR 31 + +/** + * Symbolic link loop. A loop exists in symbolic links encountered + * during pathname resolution. This error may also be returned if + * more than {SYMLOOP_MAX} symbolic links are encountered during + * pathname resolution. + */ +#define ELOOP 32 + +/** + * File descriptor value too large or too many open streams. An + * attempt was made to open a file descriptor with a value greater + * than or equal to {OPEN_MAX}, or an attempt was made to open more + * than the maximum number of streams allowed in the process. + */ +#define EMFILE 33 + +/** + * Too many links. An attempt was made to have the link count of a + * single file exceed {LINK_MAX}. + */ +#define EMLINK 34 + +/** + * Message too large. A message sent on a transport provider was + * larger than an internal message buffer or some other network limit. + * or: + * Inappropriate message buffer length. + */ +#define EMSGSIZE 35 + +/** + * Reserved. + */ +#define EMULTIHOP 36 + +/** + * Filename too long. The length of a pathname exceeds {PATH_MAX} and + * the implementation considers this to be an error, or a pathname + * component is longer than {NAME_MAX}. This error may also occur + * when pathname substitution, as a result of encountering a + * symbolic link during pathname resolution, results in a pathname + * string the size of which exceeds {PATH_MAX}. + */ +#define ENAMETOOLONG 37 + +/** + * Network is down. The local network interface used to reach the + * destination is down. + */ +#define ENETDOWN 38 + +/** + * The connection was aborted by the network. + */ +#define ENETRESET 39 + +/** + * Network unreachable. No route to the network is present. + */ +#define ENETUNREACH 40 + +/** + * Too many files open in system. Too many files are currently open + * in the system. The system has reached its predefined limit for + * simultaneously open files and temporarily cannot accept requests + * to open another one. + */ +#define ENFILE 41 + +/** + * No buffer space available. Insufficient buffer resources were + * available in the system to perform the socket operation. + */ +#define ENOBUFS 42 + +/** + * No message available. No message is available on the STREAM head + * read queue. + */ +#define ENODATA 43 + +/** + * No such device. An attempt was made to apply an inappropriate + * function to a device; for example, trying to read a write-only + * device such as a printer. + */ +#define ENODEV 44 + +/** + * No such file or directory. A component of a specified pathname + * does not exist, or the pathname is an empty string. + */ +#define ENOENT 45 + +/** + * Executable file format error. A request is made to execute a file + * that, although it has appropriate privileges, is not in the + * format required by the implementation for executable files. + */ +#define ENOEXEC 46 + +/** + * No locks available. A system-imposed limit on the number of + * simultaneous file and record locks has been reached and no more + * are currently available. + */ +#define ENOLCK 47 + +/** + * Reserved. + */ +#define ENOLINK 48 + +/** + * Not enough space. The new process image requires more memory than + * is allowed by the hardware or system-imposed memory management + * constraints. + */ +#define ENOMEM 49 + +/** + * No message of the desired type. The message queue does not contain + * a message of the required type during XSI interprocess communication. + */ +#define ENOMSG 50 + +/** + * Protocol not available. The protocol option specified to + * setsockopt() is not supported by the implementation. + */ +#define ENOPROTOOPT 51 + +/** + * No space left on a device. During the write() function on a + * regular file or when extending a directory, there is no free + * space left on the device. + */ +#define ENOSPC 52 + +/** + * No STREAM resources. Insufficient STREAMS memory resources are + * available to perform a STREAMS-related function. This is a + * temporary condition; it may be recovered from if other + * processes release resources. + */ +#define ENOSR 53 + +/** + * Not a STREAM. A STREAM function was attempted on a file descriptor + * that was not associated with a STREAMS device. + */ +#define ENOSTR 54 + +/** + * Functionality not supported. An attempt was made to use optional + * functionality that is not supported in this implementation. + */ +#define ENOSYS 55 + +/** + * Socket not connected. The socket is not connected. + */ +#define ENOTCONN 56 + +/** + * Not a directory. A component of the specified pathname exists, but + * it is not a directory, when a directory was expected; or an + * attempt was made to create a non-directory file, and the specified + * pathname contains at least one non- \ character and ends + * with one or more trailing \ characters. + */ +#define ENOTDIR 57 + +/** + * Directory not empty. A directory other than an empty directory + * was supplied when an empty directory was expected. + */ +#define ENOTEMPTY 58 + +/** + * State not recoverable. The state protected by a robust mutex + * is not recoverable. + */ +#define ENOTRECOVERABLE 59 + +/** + * Not a socket. The file descriptor does not refer to a socket. + */ +#define ENOTSOCK 60 + +/** + * Not supported. The implementation does not support the requested + * feature or value. + */ +#define ENOTSUP 61 + +/** + * Inappropriate I/O control operation. A control function has been + * attempted for a file or special file for which the operation + * is inappropriate. + */ +#define ENOTTY 62 + +/** + * No such device or address. Input or output on a special file + * refers to a device that does not exist, or makes a request + * beyond the capabilities of the device. It may also occur when, + * for example, a tape drive is not on-line. + */ +#define ENXIO 63 + +/** + * Operation not supported on socket. The type of socket (address + * family or protocol) does not support the requested operation. + */ +#define EOPNOTSUPP 64 + +/** + * Value too large to be stored in data type. An operation was + * attempted which would generate a value that is outside the + * range of values that can be represented in the relevant data + * type or that are allowed for a given data item. + */ +#define EOVERFLOW 65 + +/** + * Previous owner died. The owner of a robust mutex terminated + * while holding the mutex lock. + */ +#define EOWNERDEAD 66 + +/** + * Operation not permitted. An attempt was made to perform an + * operation limited to processes with appropriate privileges or + * to the owner of a file or other resource. + */ +#define EPERM 67 + +/** + * Broken pipe. A write was attempted on a socket, pipe, or FIFO + * for which there is no process to read the data. + */ +#define EPIPE 68 + +/** + * Protocol error. Some protocol error occurred. This error is + * device-specific, but is generally not related to a + * hardware failure. + */ +#define EPROTO 69 + +/** + * Protocol not supported. The protocol is not supported by the + * address family, or the protocol is not supported by + * the implementation. + */ +#define EPROTONOSUPPORT 70 + +/** + * Protocol wrong type for socket. The socket type is not + * supported by the protocol. + */ +#define EPROTOTYPE 71 + +/** + * Result too large or too small. The result of the function + * is too large (overflow) or too small (underflow) to be + * represented in the available space. + */ +#define ERANGE 72 + +/** + * Read-only file system. An attempt was made to modify a file + * or directory on a file system that is read-only. + */ +#define EROFS 73 + +/** + * Invalid seek. An attempt was made to access the file offset + * associated with a pipe or FIFO. + */ +#define ESPIPE 74 + +/** + * No such process. No process can be found corresponding to that + * specified by the given process ID. + */ +#define ESRCH 75 + +/** + * Reserved. + */ +#define ESTALE 76 + +/** + * STREAM ioctl() timeout. The timer set for a STREAMS ioctl() call + * has expired. The cause of this error is device-specific and could + * indicate either a hardware or software failure, or a timeout + * value that is too short for the specific operation. The status + * of the ioctl() operation is unspecified. + */ +#define ETIME 77 + +/** + * Connection timed out. The connection to a remote machine has + * timed out. + * If the connection timed out during execution of the function that + * reported this error (as opposed to timing out prior to the + * function being called), it is unspecified whether the function + * has completed some or all of the documented behavior associated + * with a successful completion of the function. + * or: + * Operation timed out. The time limit associated with the operation + * was exceeded before the operation completed. + */ +#define ETIMEDOUT 78 + +/** + * Text file busy. An attempt was made to execute a pure-procedure + * program that is currently open for writing, or an attempt has + * been made to open for writing a pure-procedure program that + * is being executed. + */ +#define ETXTBSY 79 + +/** + * Operation would block. An operation on a socket marked as + * non-blocking has encountered a situation such as no data available + * that otherwise would have caused the function to suspend execution. + */ +#define EWOULDBLOCK 80 + +/** + * Improper link. A link to a file on another file system was attempted. + */ +#define EXDEV 81 + +#ifdef __kernel__ +#define __ERRNO_MAX 82 +#endif + +#endif // !__FENNIX_API_ERRNO_H__ diff --git a/Userspace/libc/abis/fennix/generic/bits/signal.h b/Userspace/libc/abis/fennix/generic/bits/signal.h new file mode 100644 index 00000000..d55e8d6d --- /dev/null +++ b/Userspace/libc/abis/fennix/generic/bits/signal.h @@ -0,0 +1,124 @@ +/* + This file is part of Fennix C Library. + + Fennix C Library is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix C Library. If not, see . +*/ + +#ifndef __BITS_SIGNAL_H +#define __BITS_SIGNAL_H + +#include + +#define SIGNULL __SYS_SIGNULL +#define SIGABRT __SYS_SIGABRT +#define SIGALRM __SYS_SIGALRM +#define SIGBUS __SYS_SIGBUS +#define SIGCHLD __SYS_SIGCHLD +#define SIGCONT __SYS_SIGCONT +#define SIGFPE __SYS_SIGFPE +#define SIGHUP __SYS_SIGHUP +#define SIGILL __SYS_SIGILL +#define SIGINT __SYS_SIGINT +#define SIGKILL __SYS_SIGKILL +#define SIGPIPE __SYS_SIGPIPE +#define SIGQUIT __SYS_SIGQUIT +#define SIGSEGV __SYS_SIGSEGV +#define SIGSTOP __SYS_SIGSTOP +#define SIGTERM __SYS_SIGTERM +#define SIGTSTP __SYS_SIGTSTP +#define SIGTTIN __SYS_SIGTTIN +#define SIGTTOU __SYS_SIGTTOU +#define SIGUSR1 __SYS_SIGUSR1 +#define SIGUSR2 __SYS_SIGUSR2 +#define SIGPOLL __SYS_SIGPOLL +#define SIGPROF __SYS_SIGPROF +#define SIGSYS __SYS_SIGSYS +#define SIGTRAP __SYS_SIGTRAP +#define SIGURG __SYS_SIGURG +#define SIGVTALRM __SYS_SIGVTALRM +#define SIGXCPU __SYS_SIGXCPU +#define SIGXFSZ __SYS_SIGXFSZ +#define SIGCOMP1 __SYS_SIGCOMP1 +#define SIGCOMP2 __SYS_SIGCOMP2 +#define SIGCOMP3 __SYS_SIGCOMP3 +#define SIGRTMIN __SYS_SIGRTMIN +#define SIGRT_1 __SYS_SIGRT_1 +#define SIGRT_2 __SYS_SIGRT_2 +#define SIGRT_3 __SYS_SIGRT_3 +#define SIGRT_4 __SYS_SIGRT_4 +#define SIGRT_5 __SYS_SIGRT_5 +#define SIGRT_6 __SYS_SIGRT_6 +#define SIGRT_7 __SYS_SIGRT_7 +#define SIGRT_8 __SYS_SIGRT_8 +#define SIGRT_9 __SYS_SIGRT_9 +#define SIGRT_10 __SYS_SIGRT_10 +#define SIGRT_11 __SYS_SIGRT_11 +#define SIGRT_12 __SYS_SIGRT_12 +#define SIGRT_13 __SYS_SIGRT_13 +#define SIGRT_14 __SYS_SIGRT_14 +#define SIGRT_15 __SYS_SIGRT_15 +#define SIGRT_16 __SYS_SIGRT_16 +#define SIGRT_17 __SYS_SIGRT_17 +#define SIGRT_18 __SYS_SIGRT_18 +#define SIGRT_19 __SYS_SIGRT_19 +#define SIGRT_20 __SYS_SIGRT_20 +#define SIGRT_21 __SYS_SIGRT_21 +#define SIGRT_22 __SYS_SIGRT_22 +#define SIGRT_23 __SYS_SIGRT_23 +#define SIGRT_24 __SYS_SIGRT_24 +#define SIGRT_25 __SYS_SIGRT_25 +#define SIGRT_26 __SYS_SIGRT_26 +#define SIGRT_27 __SYS_SIGRT_27 +#define SIGRT_28 __SYS_SIGRT_28 +#define SIGRT_29 __SYS_SIGRT_29 +#define SIGRT_30 __SYS_SIGRT_30 +#define SIGRT_31 __SYS_SIGRT_31 +#define SIGRTMAX __SYS_SIGRTMAX +#define SIGNAL_MAX __SYS_SIGNAL_MAX + +#define SIG_TERM __SYS_SIG_TERM +// #define SIG_IGN __SYS_SIG_IGN +#define SIG_CORE __SYS_SIG_CORE +#define SIG_STOP __SYS_SIG_STOP +#define SIG_CONT __SYS_SIG_CONT + +#define SIG_BLOCK __SYS_SIG_BLOCK +#define SIG_UNBLOCK __SYS_SIG_UNBLOCK +#define SIG_SETMASK __SYS_SIG_SETMASK + +#define SA_NOCLDSTOP __SYS_SA_NOCLDSTOP +#define SA_ONSTACK __SYS_SA_ONSTACK +#define SA_RESETHAND __SYS_SA_RESETHAND +#define SA_RESTART __SYS_SA_RESTART +#define SA_SIGINFO __SYS_SA_SIGINFO +#define SA_NOCLDWAIT __SYS_SA_NOCLDWAIT +#define SA_NODEFER __SYS_SA_NODEFER + +#define SS_ONSTACK +#define SS_DISABLE + +#define MINSIGSTKSZ +#define SIGSTKSZ + +#define SIG_ERR ((void (*)(int))__SYS_SIG_ERR) +#define SIG_DFL ((void (*)(int))__SYS_SIG_DFL) +#define SIG_IGN ((void (*)(int))__SYS_SIG_IGN) + +#define SIGEV_NONE +#define SIGEV_SIGNAL +#define SIGEV_THREAD + +typedef unsigned long sigset_t; + +#endif // __BITS_SIGNAL_H diff --git a/Userspace/libc/abis/fennix/generic/bits/socket.h b/Userspace/libc/abis/fennix/generic/bits/socket.h new file mode 100644 index 00000000..7e45c2b8 --- /dev/null +++ b/Userspace/libc/abis/fennix/generic/bits/socket.h @@ -0,0 +1,34 @@ +/* + This file is part of Fennix C Library. + + Fennix C Library is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix C Library. If not, see . +*/ + +#ifndef __BITS_SOCKET_H +#define __BITS_SOCKET_H + +#define __socklen_t_defined +typedef __UINT32_TYPE__ socklen_t; + +#define __sa_family_t_defined +typedef unsigned int sa_family_t; + +#define __sockaddr_defined +struct sockaddr +{ + sa_family_t sa_family; + char sa_data[14]; +}; + +#endif // __BITS_SOCKET_H diff --git a/Userspace/libc/include/fennix/syscalls.h b/Userspace/libc/abis/fennix/generic/bits/syscalls.h similarity index 99% rename from Userspace/libc/include/fennix/syscalls.h rename to Userspace/libc/abis/fennix/generic/bits/syscalls.h index 72a89c7d..df4dcd43 100644 --- a/Userspace/libc/include/fennix/syscalls.h +++ b/Userspace/libc/abis/fennix/generic/bits/syscalls.h @@ -15,8 +15,8 @@ along with Fennix Kernel. If not, see . */ -#ifndef __FENNIX_API_SYSCALLS_LIST_H__ -#define __FENNIX_API_SYSCALLS_LIST_H__ +#ifndef __FENNIX_API_SYSTEM_CALLS_LIST_H__ +#define __FENNIX_API_SYSTEM_CALLS_LIST_H__ #pragma region Syscall Wrappers @@ -1809,4 +1809,4 @@ typedef enum /** @copydoc SYS_UNAME */ #define call_uname(buf) syscall1(SYS_UNAME, (scarg)buf) -#endif // !__FENNIX_API_SYSCALLS_LIST_H__ +#endif // !__FENNIX_API_SYSTEM_CALLS_LIST_H__ diff --git a/Userspace/libc/include/bits/libc.h b/Userspace/libc/include/bits/libc.h new file mode 100644 index 00000000..b2e95ccc --- /dev/null +++ b/Userspace/libc/include/bits/libc.h @@ -0,0 +1,70 @@ +/* + This file is part of Fennix C Library. + + Fennix C Library is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix C Library. If not, see . +*/ + +#ifndef FENNIX_BITS_LIBC_H +#define FENNIX_BITS_LIBC_H + +#include +#include +#include +#include + +#ifdef __kernel__ +#error "Kernel code should not include this header" +#endif // __kernel__ + +#ifndef export +#define export __attribute__((__visibility__("default"))) +#endif // export + +#define sysdep(name) \ + __libc_##name + +void sysdep(Exit)(int Status); +int sysdep(Accept)(int Socket, struct sockaddr *restrict Address, socklen_t *restrict AddressLength); +int sysdep(Bind)(int Socket, const struct sockaddr *Address, socklen_t AddressLength); +int sysdep(Connect)(int Socket, const struct sockaddr *Address, socklen_t AddressLength); +int sysdep(Listen)(int Socket, int Backlog); +int sysdep(Socket)(int Domain, int Type, int Protocol); +int sysdep(UnixName)(struct utsname *Name); +int sysdep(WaitProcessID)(pid_t ProcessID, int *Status, int Options); +int sysdep(IOControl)(int Descriptor, unsigned long Operation, void *Argument); +void *sysdep(MemoryMap)(void *Address, size_t Length, int Protection, int Flags, int Descriptor, off_t Offset); +int sysdep(MemoryUnmap)(void *Address, size_t Length); +int sysdep(MemoryProtect)(void *Address, size_t Length, int Protection); +int sysdep(Fork)(void); +int sysdep(Read)(int Descriptor, void *Buffer, size_t Size); +int sysdep(Write)(int Descriptor, const void *Buffer, size_t Size); +int sysdep(PRead)(int Descriptor, void *Buffer, size_t Size, off_t Offset); +int sysdep(PWrite)(int Descriptor, const void *Buffer, size_t Size, off_t Offset); +int sysdep(Open)(const char *Pathname, int Flags, mode_t Mode); +int sysdep(Close)(int Descriptor); +int sysdep(Access)(const char *Pathname, int Mode); +int sysdep(Tell)(int Descriptor); +int sysdep(Seek)(int Descriptor, off_t Offset, int Whence); +pid_t sysdep(GetProcessID)(void); +pid_t sysdep(GetParentProcessID)(void); +int sysdep(Execve)(const char *Pathname, char *const *Argv, char *const *Envp); +int sysdep(Kill)(pid_t ProcessID, int Signal); +int sysdep(Stat)(const char *Pathname, struct stat *Statbuf); +int sysdep(FStat)(int Descriptor, struct stat *Statbuf); +int sysdep(LStat)(const char *Pathname, struct stat *Statbuf); +int sysdep(Truncate)(const char *Pathname, off_t Length); +int sysdep(MakeDirectory)(const char *Pathname, mode_t Mode); +int sysdep(ProcessControl)(unsigned long Option, unsigned long Arg1, unsigned long Arg2, unsigned long Arg3, unsigned long Arg4); + +#endif // FENNIX_BITS_LIBC_H diff --git a/Userspace/libc/include/bits/types/signal.h b/Userspace/libc/include/bits/types/signal.h new file mode 100644 index 00000000..99b47cba --- /dev/null +++ b/Userspace/libc/include/bits/types/signal.h @@ -0,0 +1,36 @@ +/* + This file is part of Fennix C Library. + + Fennix C Library is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix C Library. If not, see . +*/ + +#ifndef __BITS_TYPES_SIGNAL_H +#define __BITS_TYPES_SIGNAL_H + +union sigval +{ + int sival_int; /* Integer signal value. */ + void *sival_ptr; /* Pointer signal value. */ +}; + +typedef struct sigevent +{ + int sigev_notify; /* Notification type. */ + int sigev_signo; /* Signal number. */ + union sigval sigev_value; /* Signal value. */ + void (*sigev_notify_function)(union sigval); /* Notification function. */ + pthread_attr_t *sigev_notify_attributes; /* Notification attributes. */ +} sigevent; + +#endif // __BITS_TYPES_SIGNAL_H diff --git a/Userspace/libc/include/errno.h b/Userspace/libc/include/errno.h index ee601518..451dffaa 100644 --- a/Userspace/libc/include/errno.h +++ b/Userspace/libc/include/errno.h @@ -1,592 +1,24 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix C Library. - Fennix Kernel is free software: you can redistribute it and/or + Fennix C Library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, + Fennix C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + along with Fennix C Library. If not, see . */ -#ifndef __FENNIX_API_ERRNO_H__ -#define __FENNIX_API_ERRNO_H__ +#ifndef _ERRNO_H +#define _ERRNO_H -/** - * The documentation for these error codes are from: - * https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html - * - * Full list: - * https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/basedefs/errno.h.html - */ -typedef enum -{ - /** - * No Error - */ - EOK = 0, - - /** - * Argument list too long. The sum of the number of bytes used by the - * new process image's argument list and environment list is greater - * than the system-imposed limit of {ARG_MAX} bytes. - * or: - * Lack of space in an output buffer. - * or: - * Argument is greater than the system-imposed maximum. - */ - E2BIG = 1, - - /** - * Permission denied. An attempt was made to access a file in a way - * forbidden by its file access permissions. - */ - EACCES = 2, - - /** - * Address in use. The specified address is in use. - */ - EADDRINUSE = 3, - - /** - * Address not available. The specified address is not available from - * the local system. - */ - EADDRNOTAVAIL = 4, - - /** - * Address family not supported. The implementation does not support - * the specified address family, or the specified address is not a - * valid address for the address family of the specified socket. - */ - EAFNOSUPPORT = 5, - - /** - * Resource temporarily unavailable. This is a temporary condition - * and later calls to the same routine may complete normally. - */ - EAGAIN = 6, - - /** - * Connection already in progress. A connection request is already in - * progress for the specified socket. - */ - EALREADY = 7, - - /** - * Bad file descriptor. A file descriptor argument is out of range, - * refers to no open file, or a read (write) request is made to a - * file that is only open for writing (reading). - */ - EBADF = 8, - - /** - * Bad message. During a read(), getmsg(), getpmsg(), or ioctl() - * I_RECVFD request to a STREAMS device, a message arrived at the - * head of the STREAM that is inappropriate for the function - * receiving the message. - * read() - * Message waiting to be read on a STREAM is not a data message. - * getmsg() or getpmsg() - * A file descriptor was received instead of a control message. - * ioctl() - * Control or data information was received instead of a file - * descriptor when I_RECVFD was specified. - */ - EBADMSG = 9, - - /** - * Resource busy. An attempt was made to make use of a system - * resource that is not currently available, as it is being - * used by another process in a manner that would have - * conflicted with the request being made by this process. - */ - EBUSY = 10, - - /** - * Operation canceled. The associated asynchronous operation was - * canceled before completion. - */ - ECANCELED = 11, - - /** - * No child process. A wait(), waitid(), or waitpid() function was - * executed by a process that had no existing or unwaited-for - * child process. - */ - ECHILD = 12, - - /** - * Connection aborted. The connection has been aborted. - */ - ECONNABORTED = 13, - - /** - * Connection refused. An attempt to connect to a socket was refused - * because there was no process listening or because the queue of - * connection requests was full and the underlying protocol does not - * support retransmissions. - */ - ECONNREFUSED = 14, - - /** - * Connection reset. The connection was forcibly closed by the peer. - */ - ECONNRESET = 15, - - /** - * Resource deadlock would occur. An attempt was made to lock a system - * resource that would have resulted in a deadlock situation. - */ - EDEADLK = 16, - - /** - * Destination address required. No bind address was established. - */ - EDESTADDRREQ = 17, - - /** - * Domain error. An input argument is outside the defined domain of the - * mathematical function (defined in the ISO C standard). - */ - EDOM = 18, - - /** - * Reserved. - */ - EDQUOT = 19, - - /** - * File exists. An existing file was mentioned in an inappropriate - * context; for example, as a new link name in the link() function. - */ - EEXIST = 20, - - /** - * Bad address. The system detected an invalid address in attempting - * to use an argument of a call. The reliable detection of this error - * cannot be guaranteed, and when not detected may result in the - * generation of a signal, indicating an address violation, which is - * sent to the process. - */ - EFAULT = 21, - - /** - * File too large. The size of a file would exceed the maximum file - * size of an implementation or offset maximum established in the - * corresponding file description. - */ - EFBIG = 22, - - /** - * Host is unreachable. The destination host cannot be reached - * (probably because the host is down or a remote router cannot - * reach it). - */ - EHOSTUNREACH = 23, - - /** - * Identifier removed. Returned during XSI interprocess communication - * if an identifier has been removed from the system. - */ - EIDRM = 24, - - /** - * Illegal byte sequence. A wide-character code has been detected that - * does not correspond to a valid character, or a byte sequence does - * not form a valid wide-character code (defined in the ISO C standard). - */ - EILSEQ = 25, - - /** - * Operation in progress. This code is used to indicate that an - * asynchronous operation has not yet completed. - * or: - * O_NONBLOCK is set for the socket file descriptor and the connection - * cannot be immediately established. - */ - EINPROGRESS = 26, - - /** - * Interrupted function call. An asynchronous signal was caught by the - * process during the execution of an interruptible function. If the - * signal handler performs a normal return, the interrupted function - * call may return this condition (see the Base Definitions volume - * of POSIX.1-2017, ). - */ - EINTR = 27, - - /** - * Invalid argument. Some invalid argument was supplied; for example, - * specifying an undefined signal in a signal() function or a - * kill() function. - */ - EINVAL = 28, - - /** - * Input/output error. Some physical input or output error has occurred. - * This error may be reported on a subsequent operation on the same - * file descriptor. Any other error-causing operation on the same file - * descriptor may cause the [EIO] error indication to be lost. - */ - EIO = 29, - - /** - * Socket is connected. The specified socket is already connected. - */ - EISCONN = 30, - - /** - * Is a directory. An attempt was made to open a directory with write - * mode specified. - */ - EISDIR = 31, - - /** - * Symbolic link loop. A loop exists in symbolic links encountered - * during pathname resolution. This error may also be returned if - * more than {SYMLOOP_MAX} symbolic links are encountered during - * pathname resolution. - */ - ELOOP = 32, - - /** - * File descriptor value too large or too many open streams. An - * attempt was made to open a file descriptor with a value greater - * than or equal to {OPEN_MAX}, or an attempt was made to open more - * than the maximum number of streams allowed in the process. - */ - EMFILE = 33, - - /** - * Too many links. An attempt was made to have the link count of a - * single file exceed {LINK_MAX}. - */ - EMLINK = 34, - - /** - * Message too large. A message sent on a transport provider was - * larger than an internal message buffer or some other network limit. - * or: - * Inappropriate message buffer length. - */ - EMSGSIZE = 35, - - /** - * Reserved. - */ - EMULTIHOP = 36, - - /** - * Filename too long. The length of a pathname exceeds {PATH_MAX} and - * the implementation considers this to be an error, or a pathname - * component is longer than {NAME_MAX}. This error may also occur - * when pathname substitution, as a result of encountering a - * symbolic link during pathname resolution, results in a pathname - * string the size of which exceeds {PATH_MAX}. - */ - ENAMETOOLONG = 37, - - /** - * Network is down. The local network interface used to reach the - * destination is down. - */ - ENETDOWN = 38, - - /** - * The connection was aborted by the network. - */ - ENETRESET = 39, - - /** - * Network unreachable. No route to the network is present. - */ - ENETUNREACH = 40, - - /** - * Too many files open in system. Too many files are currently open - * in the system. The system has reached its predefined limit for - * simultaneously open files and temporarily cannot accept requests - * to open another one. - */ - ENFILE = 41, - - /** - * No buffer space available. Insufficient buffer resources were - * available in the system to perform the socket operation. - */ - ENOBUFS = 42, - - /** - * No message available. No message is available on the STREAM head - * read queue. - */ - ENODATA = 43, - - /** - * No such device. An attempt was made to apply an inappropriate - * function to a device; for example, trying to read a write-only - * device such as a printer. - */ - ENODEV = 44, - - /** - * No such file or directory. A component of a specified pathname - * does not exist, or the pathname is an empty string. - */ - ENOENT = 45, - - /** - * Executable file format error. A request is made to execute a file - * that, although it has appropriate privileges, is not in the - * format required by the implementation for executable files. - */ - ENOEXEC = 46, - - /** - * No locks available. A system-imposed limit on the number of - * simultaneous file and record locks has been reached and no more - * are currently available. - */ - ENOLCK = 47, - - /** - * Reserved. - */ - ENOLINK = 48, - - /** - * Not enough space. The new process image requires more memory than - * is allowed by the hardware or system-imposed memory management - * constraints. - */ - ENOMEM = 49, - - /** - * No message of the desired type. The message queue does not contain - * a message of the required type during XSI interprocess communication. - */ - ENOMSG = 50, - - /** - * Protocol not available. The protocol option specified to - * setsockopt() is not supported by the implementation. - */ - ENOPROTOOPT = 51, - - /** - * No space left on a device. During the write() function on a - * regular file or when extending a directory, there is no free - * space left on the device. - */ - ENOSPC = 52, - - /** - * No STREAM resources. Insufficient STREAMS memory resources are - * available to perform a STREAMS-related function. This is a - * temporary condition; it may be recovered from if other - * processes release resources. - */ - ENOSR = 53, - - /** - * Not a STREAM. A STREAM function was attempted on a file descriptor - * that was not associated with a STREAMS device. - */ - ENOSTR = 54, - - /** - * Functionality not supported. An attempt was made to use optional - * functionality that is not supported in this implementation. - */ - ENOSYS = 55, - - /** - * Socket not connected. The socket is not connected. - */ - ENOTCONN = 56, - - /** - * Not a directory. A component of the specified pathname exists, but - * it is not a directory, when a directory was expected; or an - * attempt was made to create a non-directory file, and the specified - * pathname contains at least one non- \ character and ends - * with one or more trailing \ characters. - */ - ENOTDIR = 57, - - /** - * Directory not empty. A directory other than an empty directory - * was supplied when an empty directory was expected. - */ - ENOTEMPTY = 58, - - /** - * State not recoverable. The state protected by a robust mutex - * is not recoverable. - */ - ENOTRECOVERABLE = 59, - - /** - * Not a socket. The file descriptor does not refer to a socket. - */ - ENOTSOCK = 60, - - /** - * Not supported. The implementation does not support the requested - * feature or value. - */ - ENOTSUP = 61, - - /** - * Inappropriate I/O control operation. A control function has been - * attempted for a file or special file for which the operation - * is inappropriate. - */ - ENOTTY = 62, - - /** - * No such device or address. Input or output on a special file - * refers to a device that does not exist, or makes a request - * beyond the capabilities of the device. It may also occur when, - * for example, a tape drive is not on-line. - */ - ENXIO = 63, - - /** - * Operation not supported on socket. The type of socket (address - * family or protocol) does not support the requested operation. - */ - EOPNOTSUPP = 64, - - /** - * Value too large to be stored in data type. An operation was - * attempted which would generate a value that is outside the - * range of values that can be represented in the relevant data - * type or that are allowed for a given data item. - */ - EOVERFLOW = 65, - - /** - * Previous owner died. The owner of a robust mutex terminated - * while holding the mutex lock. - */ - EOWNERDEAD = 66, - - /** - * Operation not permitted. An attempt was made to perform an - * operation limited to processes with appropriate privileges or - * to the owner of a file or other resource. - */ - EPERM = 67, - - /** - * Broken pipe. A write was attempted on a socket, pipe, or FIFO - * for which there is no process to read the data. - */ - EPIPE = 68, - - /** - * Protocol error. Some protocol error occurred. This error is - * device-specific, but is generally not related to a - * hardware failure. - */ - EPROTO = 69, - - /** - * Protocol not supported. The protocol is not supported by the - * address family, or the protocol is not supported by - * the implementation. - */ - EPROTONOSUPPORT = 70, - - /** - * Protocol wrong type for socket. The socket type is not - * supported by the protocol. - */ - EPROTOTYPE = 71, - - /** - * Result too large or too small. The result of the function - * is too large (overflow) or too small (underflow) to be - * represented in the available space. - */ - ERANGE = 72, - - /** - * Read-only file system. An attempt was made to modify a file - * or directory on a file system that is read-only. - */ - EROFS = 73, - - /** - * Invalid seek. An attempt was made to access the file offset - * associated with a pipe or FIFO. - */ - ESPIPE = 74, - - /** - * No such process. No process can be found corresponding to that - * specified by the given process ID. - */ - ESRCH = 75, - - /** - * Reserved. - */ - ESTALE = 76, - - /** - * STREAM ioctl() timeout. The timer set for a STREAMS ioctl() call - * has expired. The cause of this error is device-specific and could - * indicate either a hardware or software failure, or a timeout - * value that is too short for the specific operation. The status - * of the ioctl() operation is unspecified. - */ - ETIME = 77, - - /** - * Connection timed out. The connection to a remote machine has - * timed out. - * If the connection timed out during execution of the function that - * reported this error (as opposed to timing out prior to the - * function being called), it is unspecified whether the function - * has completed some or all of the documented behavior associated - * with a successful completion of the function. - * or: - * Operation timed out. The time limit associated with the operation - * was exceeded before the operation completed. - */ - ETIMEDOUT = 78, - - /** - * Text file busy. An attempt was made to execute a pure-procedure - * program that is currently open for writing, or an attempt has - * been made to open for writing a pure-procedure program that - * is being executed. - */ - ETXTBSY = 79, - - /** - * Operation would block. An operation on a socket marked as - * non-blocking has encountered a situation such as no data available - * that otherwise would have caused the function to suspend execution. - */ - EWOULDBLOCK = 80, - - /** - * Improper link. A link to a file on another file system was attempted. - */ - EXDEV = 81, - - __ERRNO_MAX -} KernelErrors; +#include #ifdef __cplusplus extern "C" @@ -602,4 +34,4 @@ extern "C" #define errno (*__errno_location()) -#endif // !__FENNIX_API_ERRNO_H__ +#endif // _ERRNO_H diff --git a/Userspace/libc/include/signal.h b/Userspace/libc/include/signal.h index a52cb1db..5d517549 100644 --- a/Userspace/libc/include/signal.h +++ b/Userspace/libc/include/signal.h @@ -24,115 +24,11 @@ extern "C" #endif // __cplusplus #include -#include +#include #include -#define SIGNULL __SYS_SIGNULL -#define SIGABRT __SYS_SIGABRT -#define SIGALRM __SYS_SIGALRM -#define SIGBUS __SYS_SIGBUS -#define SIGCHLD __SYS_SIGCHLD -#define SIGCONT __SYS_SIGCONT -#define SIGFPE __SYS_SIGFPE -#define SIGHUP __SYS_SIGHUP -#define SIGILL __SYS_SIGILL -#define SIGINT __SYS_SIGINT -#define SIGKILL __SYS_SIGKILL -#define SIGPIPE __SYS_SIGPIPE -#define SIGQUIT __SYS_SIGQUIT -#define SIGSEGV __SYS_SIGSEGV -#define SIGSTOP __SYS_SIGSTOP -#define SIGTERM __SYS_SIGTERM -#define SIGTSTP __SYS_SIGTSTP -#define SIGTTIN __SYS_SIGTTIN -#define SIGTTOU __SYS_SIGTTOU -#define SIGUSR1 __SYS_SIGUSR1 -#define SIGUSR2 __SYS_SIGUSR2 -#define SIGPOLL __SYS_SIGPOLL -#define SIGPROF __SYS_SIGPROF -#define SIGSYS __SYS_SIGSYS -#define SIGTRAP __SYS_SIGTRAP -#define SIGURG __SYS_SIGURG -#define SIGVTALRM __SYS_SIGVTALRM -#define SIGXCPU __SYS_SIGXCPU -#define SIGXFSZ __SYS_SIGXFSZ -#define SIGCOMP1 __SYS_SIGCOMP1 -#define SIGCOMP2 __SYS_SIGCOMP2 -#define SIGCOMP3 __SYS_SIGCOMP3 -#define SIGRTMIN __SYS_SIGRTMIN -#define SIGRT_1 __SYS_SIGRT_1 -#define SIGRT_2 __SYS_SIGRT_2 -#define SIGRT_3 __SYS_SIGRT_3 -#define SIGRT_4 __SYS_SIGRT_4 -#define SIGRT_5 __SYS_SIGRT_5 -#define SIGRT_6 __SYS_SIGRT_6 -#define SIGRT_7 __SYS_SIGRT_7 -#define SIGRT_8 __SYS_SIGRT_8 -#define SIGRT_9 __SYS_SIGRT_9 -#define SIGRT_10 __SYS_SIGRT_10 -#define SIGRT_11 __SYS_SIGRT_11 -#define SIGRT_12 __SYS_SIGRT_12 -#define SIGRT_13 __SYS_SIGRT_13 -#define SIGRT_14 __SYS_SIGRT_14 -#define SIGRT_15 __SYS_SIGRT_15 -#define SIGRT_16 __SYS_SIGRT_16 -#define SIGRT_17 __SYS_SIGRT_17 -#define SIGRT_18 __SYS_SIGRT_18 -#define SIGRT_19 __SYS_SIGRT_19 -#define SIGRT_20 __SYS_SIGRT_20 -#define SIGRT_21 __SYS_SIGRT_21 -#define SIGRT_22 __SYS_SIGRT_22 -#define SIGRT_23 __SYS_SIGRT_23 -#define SIGRT_24 __SYS_SIGRT_24 -#define SIGRT_25 __SYS_SIGRT_25 -#define SIGRT_26 __SYS_SIGRT_26 -#define SIGRT_27 __SYS_SIGRT_27 -#define SIGRT_28 __SYS_SIGRT_28 -#define SIGRT_29 __SYS_SIGRT_29 -#define SIGRT_30 __SYS_SIGRT_30 -#define SIGRT_31 __SYS_SIGRT_31 -#define SIGRTMAX __SYS_SIGRTMAX -#define SIGNAL_MAX __SYS_SIGNAL_MAX - -#define SIG_TERM __SYS_SIG_TERM -// #define SIG_IGN __SYS_SIG_IGN -#define SIG_CORE __SYS_SIG_CORE -#define SIG_STOP __SYS_SIG_STOP -#define SIG_CONT __SYS_SIG_CONT - -#define SIG_BLOCK __SYS_SIG_BLOCK -#define SIG_UNBLOCK __SYS_SIG_UNBLOCK -#define SIG_SETMASK __SYS_SIG_SETMASK - -#define SA_NOCLDSTOP __SYS_SA_NOCLDSTOP -#define SA_ONSTACK __SYS_SA_ONSTACK -#define SA_RESETHAND __SYS_SA_RESETHAND -#define SA_RESTART __SYS_SA_RESTART -#define SA_SIGINFO __SYS_SA_SIGINFO -#define SA_NOCLDWAIT __SYS_SA_NOCLDWAIT -#define SA_NODEFER __SYS_SA_NODEFER - -#define SS_ONSTACK -#define SS_DISABLE - -#define MINSIGSTKSZ -#define SIGSTKSZ - -#define SIG_ERR ((void (*)(int))__SYS_SIG_ERR) -#define SIG_DFL ((void (*)(int))__SYS_SIG_DFL) -#define SIG_IGN ((void (*)(int))__SYS_SIG_IGN) - -#define SIGEV_NONE -#define SIGEV_SIGNAL -#define SIGEV_THREAD - - typedef unsigned long sigset_t; - - union sigval - { - int sival_int; /* Integer signal value. */ - void *sival_ptr; /* Pointer signal value. */ - }; +#include +#include typedef struct siginfo_t { @@ -149,15 +45,6 @@ extern "C" union sigval si_value; /* Signal value. */ } siginfo_t; - typedef struct sigevent - { - int sigev_notify; /* Notification type. */ - int sigev_signo; /* Signal number. */ - union sigval sigev_value; /* Signal value. */ - void (*sigev_notify_function)(union sigval); /* Notification function. */ - pthread_attr_t *sigev_notify_attributes; /* Notification attributes. */ - } sigevent; - struct sigaction { void (*sa_handler)(int); /* Pointer to a signal-catching function or one of the SIG_IGN or SIG_DFL. */ diff --git a/Userspace/libc/include/sys/socket.h b/Userspace/libc/include/sys/socket.h index 9173038d..18ca13d9 100644 --- a/Userspace/libc/include/sys/socket.h +++ b/Userspace/libc/include/sys/socket.h @@ -21,15 +21,26 @@ #include #include #include +#include -typedef uint32_t socklen_t; +#ifndef __socklen_t_defined +#define __socklen_t_defined +typedef __UINT32_TYPE__ socklen_t; +#endif + +#ifndef __sa_family_t_defined +#define __sa_family_t_defined typedef unsigned int sa_family_t; +#endif +#ifndef __sockaddr_defined +#define __sockaddr_defined struct sockaddr { sa_family_t sa_family; char sa_data[14]; }; +#endif #define _SS_MAXSIZE 128 #define _SS_ALIGNSIZE (sizeof(int64_t)) diff --git a/Userspace/libc/include/sys/types.h b/Userspace/libc/include/sys/types.h index 0fa16811..f4c672ea 100644 --- a/Userspace/libc/include/sys/types.h +++ b/Userspace/libc/include/sys/types.h @@ -30,10 +30,6 @@ extern "C" #define restrict __restrict__ #endif // restrict -#ifndef export -#define export __attribute__((__visibility__("default"))) -#endif // export - typedef long blkcnt_t; typedef long blksize_t; diff --git a/Userspace/libc/include/time.h b/Userspace/libc/include/time.h index dbb4ce01..00dc6d0d 100644 --- a/Userspace/libc/include/time.h +++ b/Userspace/libc/include/time.h @@ -25,7 +25,7 @@ extern "C" #include #include -#include +#include #include typedef struct tm diff --git a/Userspace/libc/interpreter/CMakeLists.txt b/Userspace/libc/interpreter/CMakeLists.txt new file mode 100644 index 00000000..51bc90ca --- /dev/null +++ b/Userspace/libc/interpreter/CMakeLists.txt @@ -0,0 +1,21 @@ +file(GLOB_RECURSE SYSDEPS_SOURCES ${SYSDEPS_PATH}/*.c ${SYSDEPS_GENERIC}/*.c) +file(GLOB_RECURSE INTERPRETER_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*.c") +list(APPEND INTERPRETER_FILES ${SYSDEPS_SOURCES}) + +add_executable(ld.so ${INTERPRETER_FILES}) + +execute_process(COMMAND git rev-parse HEAD + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_VARIABLE GIT_COMMIT + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + +if(GIT_COMMIT) + add_compile_definitions(LIBC_GIT_COMMIT="${GIT_COMMIT}") +endif() + +add_compile_definitions(FENNIX_DYNAMIC_LOADER="1") + +install(TARGETS ld.so DESTINATION lib) +target_compile_options(ld.so PRIVATE -fvisibility=hidden -fPIC) +target_link_options(ld.so PRIVATE -nostdlib -shared -fPIC -fPIE -fno-plt -Wl,-e,_dl_start) diff --git a/Userspace/libc/interpreter/Makefile b/Userspace/libc/interpreter/Makefile deleted file mode 100644 index 27713cc1..00000000 --- a/Userspace/libc/interpreter/Makefile +++ /dev/null @@ -1,40 +0,0 @@ -default: - $(error Do not run this Makefile directly!) - -OBJECT_NAME := ld.so - -OUTPUT_DIR=$(WORKSPACE_DIR)/out/lib/ -SYSROOT = --sysroot=$(WORKSPACE_DIR)/out/ - -S_SOURCES = $(shell find ./ -type f -name '*.S') -C_SOURCES = $(shell find ./ -type f -name '*.c') -CXX_SOURCES = $(shell find ./ -type f -name '*.cpp') -OBJ = ${S_SOURCES:.S=.o} ${C_SOURCES:.c=.o} ${CXX_SOURCES:.cpp=.o} - -CFLAGS := -fvisibility=hidden -fPIC -I$(WORKSPACE_DIR)/out/include -DLIBC_GIT_COMMIT='"$(shell git rev-parse HEAD)"' - -ifeq ($(DEBUG), 1) - CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -endif - -build: $(OBJECT_NAME) - -$(OBJECT_NAME): $(OBJ) - $(info Linking $@) - $(CC) -nostdlib -shared -fPIC -fPIE -fno-plt -Wl,-soname,$(OBJECT_NAME) $(SYSROOT) $(OBJ) -o $(OBJECT_NAME) - cp $(OBJECT_NAME) $(OUTPUT_DIR)$(OBJECT_NAME) - -%.o: %.c - $(info Compiling $<) - $(CC) $(CFLAGS) -std=c17 -c $< -o $@ - -%.o: %.cpp - $(info Compiling $<) - $(CC) $(CFLAGS) -std=c++20 -c $< -o $@ - -%.o: %.S - $(info Compiling $<) - $(AS) -c $< -o $@ - -clean: - rm -f $(OBJ) $(OBJECT_NAME) diff --git a/Userspace/libc/interpreter/alloc.c b/Userspace/libc/interpreter/alloc.c index 04246328..a9739edd 100644 --- a/Userspace/libc/interpreter/alloc.c +++ b/Userspace/libc/interpreter/alloc.c @@ -15,8 +15,9 @@ along with Fennix C Library. If not, see . */ -#include +#include #include +#include #include #include #include @@ -39,7 +40,7 @@ MemoryBlock *memory_pool = NULL; void *request_page(size_t size) { size_t aligned_size = (size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); - void *addr = (void *)call_mmap(NULL, aligned_size, __SYS_PROT_READ | __SYS_PROT_WRITE, __SYS_MAP_ANONYMOUS | __SYS_MAP_PRIVATE, -1, 0); + void *addr = (void *)sysdep(MemoryMap)(NULL, aligned_size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); if ((intptr_t)addr < 0) return NULL; return addr; @@ -48,7 +49,7 @@ void *request_page(size_t size) void free_page(void *addr, size_t size) { size_t aligned_size = (size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); - call_munmap(addr, aligned_size); + sysdep(MemoryUnmap)(addr, aligned_size); } MemoryBlock *allocate_block(size_t slot_size) diff --git a/Userspace/libc/interpreter/helper.c b/Userspace/libc/interpreter/helper.c index d22d392d..9a3e1d6a 100644 --- a/Userspace/libc/interpreter/helper.c +++ b/Userspace/libc/interpreter/helper.c @@ -15,7 +15,7 @@ along with Fennix C Library. If not, see . */ -#include +#include #include #include #include diff --git a/Userspace/libc/interpreter/load.c b/Userspace/libc/interpreter/load.c index 5d8084d3..98f3747a 100644 --- a/Userspace/libc/interpreter/load.c +++ b/Userspace/libc/interpreter/load.c @@ -15,11 +15,14 @@ along with Fennix C Library. If not, see . */ -#include +#include #include +#include #include #include #include +#include +#include #include #include "elf.h" @@ -167,9 +170,15 @@ __attribute__((noinline)) void *_dl_fixup(ElfInfo *Info, long RelIndex) return ret; } +#ifdef __fennix__ +#include +#endif + int _dl_preload() { +#ifdef __fennix__ call_api_version(0); +#endif /* TODO: Do aditional checks for miscellaneous things */ @@ -353,16 +362,16 @@ void ProcessNeededLibraries(Elf_Dyn *elem, ElfInfo *Info) strcpy(fullLibPath, "/lib/"); strcat(fullLibPath, libPath); /* TODO: more checks and also check environment variables */ - if (call_access(fullLibPath, __SYS_F_OK) != 0) + if (sysdep(Access)(fullLibPath, F_OK) != 0) { printf("dl: Can't access %s\n", fullLibPath); return; } - int fd = call_open(fullLibPath, __SYS_O_RDONLY, 0644); + int fd = sysdep(Open)(fullLibPath, O_RDONLY, 0644); int status = LoadElf(fd, fullLibPath, &info); elem->d_un.d_ptr = (uintptr_t)info; /* if LoadElf fails, info will still be NULL */ - call_close(fd); + sysdep(Close)(fd); if (status < 0) /* announce that LoadElf failed */ printf("dl: Can't load %s\n", fullLibPath); } @@ -431,7 +440,7 @@ int LoadElfPhdrDYN(int fd, ElfInfo *Info) for (Elf_Half i = 0; i < header.e_phnum; i++) { - ssize_t read = call_pread(fd, &phdr, sizeof(Elf_Phdr), header.e_phoff + (header.e_phentsize * i)); + ssize_t read = sysdep(PRead)(fd, &phdr, sizeof(Elf_Phdr), header.e_phoff + (header.e_phentsize * i)); if (read != sizeof(Elf_Phdr)) { printf("dl: Can't read program header %d\n", i); @@ -450,23 +459,23 @@ int LoadElfPhdrDYN(int fd, ElfInfo *Info) int mmapProt = 0; if (phdr.p_flags & PF_X) - mmapProt |= __SYS_PROT_EXEC; + mmapProt |= PROT_EXEC; if (phdr.p_flags & PF_W) - mmapProt |= __SYS_PROT_WRITE; + mmapProt |= PROT_WRITE; if (phdr.p_flags & PF_R) - mmapProt |= __SYS_PROT_READ; + mmapProt |= PROT_READ; off_t sectionOffset = ALIGN_DOWN(phdr.p_vaddr, phdr.p_align); size_t sectionSize = ALIGN_UP(phdr.p_memsz + (phdr.p_vaddr - sectionOffset), phdr.p_align); - uintptr_t section = call_mmap(base + sectionOffset, - sectionSize, mmapProt, - __SYS_MAP_ANONYMOUS | __SYS_MAP_PRIVATE | __SYS_MAP_FIXED, - -1, 0); + uintptr_t section = (uintptr_t)sysdep(MemoryMap)((void *)(base + sectionOffset), + sectionSize, mmapProt, + MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, + -1, 0); sectionOffset = phdr.p_vaddr - ALIGN_DOWN(phdr.p_vaddr, phdr.p_align); if (phdr.p_filesz > 0) { - ssize_t read = call_pread(fd, section + sectionOffset, phdr.p_filesz, phdr.p_offset); + ssize_t read = sysdep(PRead)(fd, (void *)(section + sectionOffset), phdr.p_filesz, phdr.p_offset); if (read != phdr.p_filesz) { printf("dl: Can't read segment %d in PT_LOAD\n", i); @@ -495,15 +504,15 @@ int LoadElfPhdrDYN(int fd, ElfInfo *Info) { int mmapProt = 0; if (phdr.p_flags & PF_X) - mmapProt |= __SYS_PROT_EXEC; + mmapProt |= PROT_EXEC; if (phdr.p_flags & PF_W) - mmapProt |= __SYS_PROT_WRITE; + mmapProt |= PROT_WRITE; if (phdr.p_flags & PF_R) - mmapProt |= __SYS_PROT_READ; + mmapProt |= PROT_READ; - dynamicTable = (Elf_Dyn *)call_mmap(0, ALIGN_UP(phdr.p_memsz, phdr.p_align), - mmapProt, __SYS_MAP_ANONYMOUS | __SYS_MAP_PRIVATE | __SYS_MAP_FIXED, - -1, 0); + dynamicTable = (Elf_Dyn *)sysdep(MemoryMap)(0, ALIGN_UP(phdr.p_memsz, phdr.p_align), + mmapProt, MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, + -1, 0); if ((intptr_t)dynamicTable <= 0) { @@ -511,7 +520,7 @@ int LoadElfPhdrDYN(int fd, ElfInfo *Info) return (int)(uintptr_t)dynamicTable; } - read = call_pread(fd, dynamicTable, phdr.p_memsz, phdr.p_offset); + read = sysdep(PRead)(fd, dynamicTable, phdr.p_memsz, phdr.p_offset); if (read != phdr.p_memsz) { printf("dl: Can't read PT_DYNAMIC\n"); @@ -598,7 +607,7 @@ int LoadElf(int fd, char *Path, ElfInfo **Out) } Elf_Ehdr header; - call_pread(fd, &header, sizeof(Elf_Ehdr), 0); + sysdep(PRead)(fd, &header, sizeof(Elf_Ehdr), 0); int status = CheckElfEhdr(&header, Path); if (status != 0) @@ -606,11 +615,11 @@ int LoadElf(int fd, char *Path, ElfInfo **Out) info = AllocateLib(); info->Header = header; - info->Path = (char *)call_mmap(0, - ALIGN_UP(strlen(Path) + 1, 0x1000 /* TODO: get page size from kernel */), - __SYS_PROT_READ, - __SYS_MAP_ANONYMOUS | __SYS_MAP_PRIVATE, - -1, 0); + info->Path = (char *)sysdep(MemoryMap)(0, + ALIGN_UP(strlen(Path) + 1, 0x1000 /* TODO: get page size from kernel */), + PROT_READ, + MAP_ANONYMOUS | MAP_PRIVATE, + -1, 0); if ((intptr_t)info->Path <= 0) { printf("dl: Can't allocate memory for path\n"); @@ -648,7 +657,7 @@ int LoadElf(int fd, char *Path, ElfInfo **Out) if (status < 0) { - call_munmap((uintptr_t)info->Path, ALIGN_UP(strlen(Path) + 1, 0x1000)); + sysdep(MemoryUnmap)((void *)info->Path, ALIGN_UP(strlen(Path) + 1, 0x1000)); FreeLib(info); return status; } @@ -956,18 +965,18 @@ int _dl_main(int argc, char *argv[], char *envp[]) { char *path = argv[0]; ElfInfo *info = NULL; - if (call_access(path, __SYS_F_OK) < 0) + if (sysdep(Access)(path, F_OK) < 0) { printf("dl: Can't access file %s\n", path); return -EACCES; } - int fd = call_open(path, __SYS_O_RDONLY, 0644); + int fd = sysdep(Open)(path, O_RDONLY, 0644); int status = LoadElf(fd, path, &info); if (status < 0) { printf("%s: Can't load ELF file\n", path); - call_close(fd); + sysdep(Close)(fd); return status; } @@ -975,11 +984,11 @@ int _dl_main(int argc, char *argv[], char *envp[]) if (status < 0) { printf("%s: Can't relocate ELF file\n", path); - call_close(fd); + sysdep(Close)(fd); return status; } - call_close(fd); + sysdep(Close)(fd); Elf_Addr entry = info->BaseAddress + info->Header.e_entry; return ((int (*)(int, char *[], char *[]))entry)(argc, argv, envp); } diff --git a/Userspace/libc/interpreter/nanoprintf.h b/Userspace/libc/interpreter/nanoprintf.h index f8362e06..d136715c 100644 --- a/Userspace/libc/interpreter/nanoprintf.h +++ b/Userspace/libc/interpreter/nanoprintf.h @@ -1,4 +1,4 @@ -/* nanoprintf v0.5.3: a tiny embeddable printf replacement written in C. +/* nanoprintf v0.5.4: a tiny embeddable printf replacement written in C. https://github.com/charlesnicholson/nanoprintf charles.nicholson+nanoprintf@gmail.com dual-licensed under 0bsd and unlicense, take your pick. see eof for details. */ @@ -336,6 +336,7 @@ static int npf_parse_format_spec(char const *format, npf_format_spec_t *out_spec } #if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 + out_spec->field_width = 0; out_spec->field_width_opt = NPF_FMT_SPEC_OPT_NONE; if (*cur == '*') { @@ -344,7 +345,6 @@ static int npf_parse_format_spec(char const *format, npf_format_spec_t *out_spec } else { - out_spec->field_width = 0; while ((*cur >= '0') && (*cur <= '9')) { out_spec->field_width_opt = NPF_FMT_SPEC_OPT_LITERAL; diff --git a/Userspace/libc/interpreter/print.c b/Userspace/libc/interpreter/print.c index b4dc9823..8e2d96f6 100644 --- a/Userspace/libc/interpreter/print.c +++ b/Userspace/libc/interpreter/print.c @@ -17,7 +17,8 @@ #include #include -#include +#include +#include #include "elf.h" #include "misc.h" @@ -31,7 +32,7 @@ void flush_buffer() { if (print_buffer_offset > 0) { - call_write(1, print_buffer, print_buffer_offset); + sysdep(Write)(1, print_buffer, print_buffer_offset); print_buffer_offset = 0; } } @@ -45,11 +46,11 @@ void print_wrapper(int c, void *) void __init_print_buffer() { - print_buffer = (char *)call_mmap(0, - 0x1000, - __SYS_PROT_READ | __SYS_PROT_WRITE, - __SYS_MAP_PRIVATE | __SYS_MAP_ANONYMOUS, - -1, 0); + print_buffer = (char *)sysdep(MemoryMap)(0, + 0x1000, + PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, + -1, 0); print_buffer_size = 0x1000; print_buffer_offset = 0; } @@ -58,7 +59,7 @@ void __fini_print_buffer() { flush_buffer(); if (print_buffer != NULL) - call_munmap(print_buffer, 0x1000); + sysdep(MemoryUnmap)(print_buffer, 0x1000); print_buffer = NULL; } diff --git a/Userspace/libc/interpreter/start.c b/Userspace/libc/interpreter/start.c index 0a99e591..238f9e56 100644 --- a/Userspace/libc/interpreter/start.c +++ b/Userspace/libc/interpreter/start.c @@ -15,7 +15,7 @@ along with Fennix C Library. If not, see . */ -#include +#include // const char __interp[] __attribute__((section(".interp"))) = "/boot/fennix.elf"; @@ -97,54 +97,11 @@ const struct void __init_print_buffer(); void __fini_print_buffer(); -__attribute__((naked, used, no_stack_protector)) void _start() -{ -#if defined(__amd64__) - __asm__( - "xorq %rbp, %rbp\n" /* Clear rbp */ - - "push %rdi\n" - "push %rsi\n" - "push %rdx\n" - "push %rcx\n" - "push %r8\n" - "push %r9\n" - - "call __init_print_buffer\n" /* Call __init_print_buffer */ - "call _dl_preload\n" /* Call _dl_preload */ - "movl %eax, %edi\n" /* Move return value to edi */ - "cmp $0, %edi\n" /* Check if return value is 0 */ - "jne _exit\n" /* If not, jump to _exit */ - - "pop %r9\n" - "pop %r8\n" - "pop %rcx\n" - "pop %rdx\n" - "pop %rsi\n" - "pop %rdi\n" - - "call main\n" /* Call _dl_main */ - "movl %eax, %edi\n" /* Move return value to edi */ - "call _exit\n"); /* Call _exit */ -#elif defined(__i386__) -#warning "i386 _start not implemented" -#elif defined(__arm__) -#warning "arm _start not implemented" -#elif defined(__aarch64__) -#warning "aarch64 _start not implemented" -#else -#error "Unsupported architecture" -#endif -} - __attribute__((no_stack_protector)) _Noreturn void _exit(int status) { __fini_print_buffer(); - call_exit(status); -/* At this point, the program *SHOULD* have exited. */ -#if defined(__amd64__) || defined(__i386__) - __asm__("ud2\n"); -#endif + sysdep(Exit)(status); + /* At this point, the program *SHOULD* have exited. */ __builtin_unreachable(); } diff --git a/Userspace/libc/libs/CMakeLists.txt b/Userspace/libc/libs/CMakeLists.txt new file mode 100644 index 00000000..fa561e76 --- /dev/null +++ b/Userspace/libc/libs/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.10) +project(FennixStandardLibraries) + +add_subdirectory(libm) +add_subdirectory(libstdc++) diff --git a/Userspace/libc/libs/libm/CMakeLists.txt b/Userspace/libc/libs/libm/CMakeLists.txt new file mode 100644 index 00000000..dacca73c --- /dev/null +++ b/Userspace/libc/libs/libm/CMakeLists.txt @@ -0,0 +1,15 @@ +cmake_minimum_required(VERSION 3.10) +project(FennixMathLibrary) + +set(SOURCES libm.c) + +add_library(m STATIC ${SOURCES}) +add_library(m_shared SHARED ${SOURCES}) + +target_link_options(m_shared PRIVATE -nostdlib) +set_target_properties(m_shared PROPERTIES OUTPUT_NAME "m") + +install(TARGETS m m_shared + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib + PUBLIC_HEADER DESTINATION include) diff --git a/Userspace/libs/libm/libm.c b/Userspace/libc/libs/libm/libm.c similarity index 100% rename from Userspace/libs/libm/libm.c rename to Userspace/libc/libs/libm/libm.c diff --git a/Userspace/libc/libs/libstdc++/CMakeLists.txt b/Userspace/libc/libs/libstdc++/CMakeLists.txt new file mode 100644 index 00000000..7407e391 --- /dev/null +++ b/Userspace/libc/libs/libstdc++/CMakeLists.txt @@ -0,0 +1,15 @@ +cmake_minimum_required(VERSION 3.10) +project(FennixStandardC++Library) + +set(SOURCES libstdc++.cpp) + +add_library(stdc++ STATIC ${SOURCES}) +add_library(stdc++_shared SHARED ${SOURCES}) + +target_link_options(stdc++_shared PRIVATE -nostdlib) +set_target_properties(stdc++_shared PROPERTIES OUTPUT_NAME "stdc++") + +install(TARGETS stdc++ stdc++_shared + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib + PUBLIC_HEADER DESTINATION include) diff --git a/Userspace/libs/libstdc++/libstdc++.c b/Userspace/libc/libs/libstdc++/libstdc++.cpp similarity index 100% rename from Userspace/libs/libstdc++/libstdc++.c rename to Userspace/libc/libs/libstdc++/libstdc++.cpp diff --git a/Userspace/libc/runtime/CMakeLists.txt b/Userspace/libc/runtime/CMakeLists.txt new file mode 100644 index 00000000..f031215b --- /dev/null +++ b/Userspace/libc/runtime/CMakeLists.txt @@ -0,0 +1,18 @@ +cmake_minimum_required(VERSION 3.10) +project(FennixRuntime) + +if(NOT DEFINED TARGET_OS) + message(FATAL_ERROR "TARGET_OS is not set") +endif() + +if(NOT DEFINED TARGET_ARCH) + message(FATAL_ERROR "TARGET_ARCH is not set") +endif() + +set(RUNTIME_DIR "${CMAKE_CURRENT_SOURCE_DIR}/${TARGET_OS}/${TARGET_ARCH}") + +if(NOT EXISTS "${RUNTIME_DIR}/CMakeLists.txt") + message(FATAL_ERROR "No runtime support for ${TARGET_OS}/${TARGET_ARCH}") +endif() + +add_subdirectory(${RUNTIME_DIR}) diff --git a/Userspace/libc/runtime/Makefile b/Userspace/libc/runtime/Makefile deleted file mode 100644 index 424b8812..00000000 --- a/Userspace/libc/runtime/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -default: - $(error Do not run this Makefile directly!) - -S_SOURCES = $(shell find ./ -type f -name '*.S') -C_SOURCES = $(shell find ./ -type f -name '*.c') -CXX_SOURCES = $(shell find ./ -type f -name '*.cpp') -OBJ = ${S_SOURCES:.S=.o} ${C_SOURCES:.c=.o} ${CXX_SOURCES:.cpp=.o} - -CRTBEGIN_PATH = $(shell $(CC) -print-file-name=crtbegin.o) -CRTEND_PATH = $(shell $(CC) -print-file-name=crtend.o) -CRTI_PATH = $(shell $(CC) -print-file-name=crti.o) -CRTN_PATH = $(shell $(CC) -print-file-name=crtn.o) - -build: $(OBJ) - cp $^ ../../out/lib/ - cp $(CRTBEGIN_PATH) $(CRTEND_PATH) $(CRTI_PATH) $(CRTN_PATH) $(WORKSPACE_DIR)/out/lib/ - -%.o: %.c - $(info Compiling $<) - $(CC) -nostdlib -std=c17 -DLIBC_GIT_COMMIT='"$(shell git rev-parse HEAD)"' -c $< -o $@ - -%.o: %.S - $(info Compiling $<) - $(AS) -c $< -o $@ - -clean: - rm -f $(OBJ) diff --git a/Userspace/libc/runtime/fennix/amd64/CMakeLists.txt b/Userspace/libc/runtime/fennix/amd64/CMakeLists.txt new file mode 100644 index 00000000..e5b40d14 --- /dev/null +++ b/Userspace/libc/runtime/fennix/amd64/CMakeLists.txt @@ -0,0 +1,34 @@ +cmake_minimum_required(VERSION 3.10) +project(FennixRuntime_${TARGET_OS}_${TARGET_ARCH}) + +find_program(COMPILER_PATH NAMES $ENV{CC} gcc REQUIRED) + +set(LIB_OUTPUT_DIR "${CMAKE_INSTALL_PREFIX}/lib") +file(MAKE_DIRECTORY ${LIB_OUTPUT_DIR}) + +add_custom_target(copy_crt_files ALL + COMMAND ${COMPILER_PATH} -print-file-name=libgcc.a | xargs cp -t ${LIB_OUTPUT_DIR} + COMMAND ${COMPILER_PATH} -print-file-name=crtbegin.o | xargs cp -t ${LIB_OUTPUT_DIR} + COMMAND ${COMPILER_PATH} -print-file-name=crtend.o | xargs cp -t ${LIB_OUTPUT_DIR} + COMMAND ${COMPILER_PATH} -print-file-name=crti.o | xargs cp -t ${LIB_OUTPUT_DIR} + COMMAND ${COMPILER_PATH} -print-file-name=crtn.o | xargs cp -t ${LIB_OUTPUT_DIR} + COMMENT "Copying CRT files" +) + +file(GLOB CRT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.c") +set(OBJECT_FILES "") +foreach(source ${CRT_SOURCES}) + get_filename_component(name ${source} NAME_WE) + set(obj "${CMAKE_BINARY_DIR}/${name}.o") + add_custom_command( + OUTPUT ${obj} + COMMAND ${COMPILER_PATH} -c ${source} -o ${obj} + DEPENDS ${source} + ) + list(APPEND OBJECT_FILES ${obj}) +endforeach() + +if(OBJECT_FILES) + add_custom_target(crt_objects ALL DEPENDS ${OBJECT_FILES}) + install(FILES ${OBJECT_FILES} DESTINATION lib) +endif() diff --git a/Userspace/libc/runtime/Scrt1.c b/Userspace/libc/runtime/fennix/amd64/Scrt1.c similarity index 100% rename from Userspace/libc/runtime/Scrt1.c rename to Userspace/libc/runtime/fennix/amd64/Scrt1.c diff --git a/Userspace/libc/runtime/crt1.c b/Userspace/libc/runtime/fennix/amd64/crt1.c similarity index 100% rename from Userspace/libc/runtime/crt1.c rename to Userspace/libc/runtime/fennix/amd64/crt1.c diff --git a/Userspace/libc/runtime/linux/x86_64/CMakeLists.txt b/Userspace/libc/runtime/linux/x86_64/CMakeLists.txt new file mode 100644 index 00000000..b24c364c --- /dev/null +++ b/Userspace/libc/runtime/linux/x86_64/CMakeLists.txt @@ -0,0 +1,43 @@ +cmake_minimum_required(VERSION 3.10) +project(FennixRuntime_${TARGET_OS}_${TARGET_ARCH}) + +find_program(COMPILER_PATH NAMES $ENV{CC} gcc REQUIRED) + +set(BUILD_OUTPUT_DIR "${CMAKE_BINARY_DIR}/lib") +set(INSTALL_OUTPUT_DIR "${CMAKE_INSTALL_PREFIX}/lib") + +file(MAKE_DIRECTORY ${BUILD_OUTPUT_DIR}) + +execute_process(COMMAND ${COMPILER_PATH} -print-file-name=crtbegin.o OUTPUT_VARIABLE CRTBEGIN_PATH OUTPUT_STRIP_TRAILING_WHITESPACE) +execute_process(COMMAND ${COMPILER_PATH} -print-file-name=crtend.o OUTPUT_VARIABLE CRTEND_PATH OUTPUT_STRIP_TRAILING_WHITESPACE) +execute_process(COMMAND ${COMPILER_PATH} -print-file-name=crti.o OUTPUT_VARIABLE CRTI_PATH OUTPUT_STRIP_TRAILING_WHITESPACE) +execute_process(COMMAND ${COMPILER_PATH} -print-file-name=crtn.o OUTPUT_VARIABLE CRTN_PATH OUTPUT_STRIP_TRAILING_WHITESPACE) + +add_custom_target(copy_crt_files ALL + COMMAND cp ${CRTBEGIN_PATH} ${CRTEND_PATH} ${CRTI_PATH} ${CRTN_PATH} ${BUILD_OUTPUT_DIR} + COMMENT "Copying CRT files" +) + +file(GLOB CRT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.c") +set(OBJECT_FILES "") + +foreach(source ${CRT_SOURCES}) + get_filename_component(name ${source} NAME_WE) + set(obj "${BUILD_OUTPUT_DIR}/${name}.o") + add_custom_command( + OUTPUT ${obj} + COMMAND ${COMPILER_PATH} -c ${source} -o ${obj} + DEPENDS ${source} + ) + list(APPEND OBJECT_FILES ${obj}) +endforeach() + +if(OBJECT_FILES) + add_custom_target(crt_objects ALL DEPENDS ${OBJECT_FILES}) +endif() + +install(FILES ${BUILD_OUTPUT_DIR}/crtbegin.o ${BUILD_OUTPUT_DIR}/crtend.o ${BUILD_OUTPUT_DIR}/crti.o ${BUILD_OUTPUT_DIR}/crtn.o + DESTINATION lib +) + +install(FILES ${OBJECT_FILES} DESTINATION lib) diff --git a/Userspace/libc/src/CMakeLists.txt b/Userspace/libc/src/CMakeLists.txt new file mode 100644 index 00000000..0678713a --- /dev/null +++ b/Userspace/libc/src/CMakeLists.txt @@ -0,0 +1,33 @@ +file(GLOB_RECURSE SRC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.c ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) +file(GLOB_RECURSE SYSDEPS_SOURCES ${SYSDEPS_PATH}/*.c ${SYSDEPS_GENERIC}/*.c ${SYSDEPS_PATH}/*.cpp ${SYSDEPS_GENERIC}/*.cpp) +list(APPEND SRC_FILES ${SYSDEPS_SOURCES}) + +add_library(libc_obj OBJECT ${SRC_FILES}) +set_target_properties(libc_obj PROPERTIES POSITION_INDEPENDENT_CODE 1) + +message(STATUS "Adding sysdeps sources: ${SYSDEPS_SOURCES}") + +add_library(libc_shared SHARED $) +set_target_properties(libc_shared PROPERTIES OUTPUT_NAME "c") +target_compile_definitions(libc_shared PRIVATE PROGRAM_VERSION="${PROJECT_VERSION}") + +execute_process( + COMMAND git rev-parse HEAD + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_VARIABLE GIT_COMMIT + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE +) + +if(GIT_COMMIT) + target_compile_definitions(libc_shared PRIVATE LIBC_GIT_COMMIT="${GIT_COMMIT}") +endif() + +target_compile_options(libc_shared PRIVATE -fvisibility=hidden -fPIC) +target_link_options(libc_shared PRIVATE -nostdlib -shared -fPIC -fPIE -e _start -Wl,-soname,libc.so -lgcc) + +add_library(libc_static STATIC $) +set_target_properties(libc_static PROPERTIES OUTPUT_NAME "c") +target_compile_options(libc_static PRIVATE -fvisibility=hidden -fPIC) + +install(TARGETS libc_shared libc_static DESTINATION lib) diff --git a/Userspace/libc/src/Makefile b/Userspace/libc/src/Makefile deleted file mode 100644 index 00efb9b6..00000000 --- a/Userspace/libc/src/Makefile +++ /dev/null @@ -1,48 +0,0 @@ -default: - $(error Do not run this Makefile directly!) - -DYNAMIC_NAME := libc.so -STATIC_NAME := libc.a - -OUTPUT_DIR=$(WORKSPACE_DIR)/out/lib/ -SYSROOT = --sysroot=$(WORKSPACE_DIR)/out/ - -S_SOURCES = $(shell find ./ -type f -name '*.S') -C_SOURCES = $(shell find ./ -type f -name '*.c') -CXX_SOURCES = $(shell find ./ -type f -name '*.cpp') -OBJ = ${S_SOURCES:.S=.o} ${C_SOURCES:.c=.o} ${CXX_SOURCES:.cpp=.o} - -CFLAGS := -fvisibility=hidden -fPIC -I../include -I$(WORKSPACE_DIR)/out/include -DLIBC_GIT_COMMIT='"$(shell git rev-parse HEAD)"' - -ifeq ($(DEBUG), 1) - CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -endif - -build: $(DYNAMIC_NAME) $(STATIC_NAME) - -.PHONY: $(DYNAMIC_NAME) $(STATIC_NAME) - -$(DYNAMIC_NAME): $(OBJ) - $(info Linking $@) - $(CC) -nostdlib -shared -fPIC -fPIE -e _start -Wl,-soname,$(DYNAMIC_NAME) $(SYSROOT) $(OBJ) -o $(DYNAMIC_NAME) -lgcc - cp $(DYNAMIC_NAME) $(OUTPUT_DIR)$(DYNAMIC_NAME) - -$(STATIC_NAME): $(OBJ) - $(info Linking $@) - $(AR) -rcs $(STATIC_NAME) $(OBJ) - cp $(STATIC_NAME) $(OUTPUT_DIR)$(STATIC_NAME) - -%.o: %.c - $(info Compiling $<) - $(CC) $(CFLAGS) -std=c17 -c $< -o $@ - -%.o: %.cpp - $(info Compiling $<) - $(CC) $(CFLAGS) -std=c++20 -c $< -o $@ - -%.o: %.S - $(info Compiling $<) - $(AS) -c $< -o $@ - -clean: - rm -f $(OBJ) $(DYNAMIC_NAME) $(STATIC_NAME) diff --git a/Userspace/libc/src/init.c b/Userspace/libc/src/init.c index ae1fd682..0d61c3b5 100644 --- a/Userspace/libc/src/init.c +++ b/Userspace/libc/src/init.c @@ -15,8 +15,7 @@ along with Fennix Userspace. If not, see . */ -#include - +#include #include int __init_pthread(void); @@ -34,7 +33,7 @@ __attribute__((visibility("default"))) void _exit(int Code) { fflush(stdout); fflush(stderr); - call_exit(Code); + sysdep(Exit)(Code); while (1) ; } diff --git a/Userspace/libc/src/main.c b/Userspace/libc/src/main.c index ae568fe5..d8d1161d 100644 --- a/Userspace/libc/src/main.c +++ b/Userspace/libc/src/main.c @@ -15,8 +15,6 @@ along with Fennix C Library. If not, see . */ -#include "../runtime/crt1.c" - const char __interp[] __attribute__((section(".interp"))) = "/lib/ld.so"; #ifndef LIBC_GIT_COMMIT @@ -47,6 +45,23 @@ const char __interp[] __attribute__((section(".interp"))) = "/lib/ld.so"; CONVERT_TO_BYTE(hex[36], hex[37]), \ CONVERT_TO_BYTE(hex[38], hex[39])} +typedef struct Elf_Nhdr +{ + __UINT32_TYPE__ n_namesz; + __UINT32_TYPE__ n_descsz; + __UINT32_TYPE__ n_type; + char n_name[]; +} __attribute__((packed)) Elf_Nhdr; + +/* These are declared in GNU ld */ +enum +{ + NT_FNX_ABI_TAG = 1, + NT_FNX_VERSION = 2, + NT_FNX_BUILD_ID = 3, + NT_FNX_ARCH = 4 +}; + const struct { Elf_Nhdr header; diff --git a/Userspace/libc/src/std/arpa/inet.c b/Userspace/libc/src/std/arpa/inet.c index aa0b4933..9552593b 100644 --- a/Userspace/libc/src/std/arpa/inet.c +++ b/Userspace/libc/src/std/arpa/inet.c @@ -15,6 +15,7 @@ along with Fennix C Library. If not, see . */ +#include #include #include diff --git a/Userspace/libc/src/std/errno.c b/Userspace/libc/src/std/errno.c index 6318bea1..9e20895d 100644 --- a/Userspace/libc/src/std/errno.c +++ b/Userspace/libc/src/std/errno.c @@ -15,10 +15,15 @@ along with Fennix C Library. If not, see . */ +#include #include #include #include +#ifndef EOK +#define EOK 0 +#endif + __iptr __check_errno(__iptr status, __iptr err) { if ((int)status >= EOK) @@ -37,9 +42,6 @@ export char *strerror(int errnum) if (errnum < 0) errnum = -errnum; - if (errnum > __ERRNO_MAX) - return (char *)"Not a valid error number"; - switch (errnum) { case EOK: diff --git a/Userspace/libc/src/std/fcntl.c b/Userspace/libc/src/std/fcntl.c index 152d3310..e99278ae 100644 --- a/Userspace/libc/src/std/fcntl.c +++ b/Userspace/libc/src/std/fcntl.c @@ -15,8 +15,8 @@ along with Fennix C Library. If not, see . */ +#include #include - #include #include #include @@ -37,7 +37,7 @@ export int open(const char *path, int oflag, ...) mode = va_arg(args, mode_t); va_end(args); } - return __check_errno(call_open(path, oflag, mode), -1); + return __check_errno(sysdep(Open)(path, oflag, mode), -1); } export int openat(int fd, const char *path, int oflag, ...); diff --git a/Userspace/libc/src/std/fenv.c b/Userspace/libc/src/std/fenv.c index 794fc9ac..e572a321 100644 --- a/Userspace/libc/src/std/fenv.c +++ b/Userspace/libc/src/std/fenv.c @@ -15,6 +15,7 @@ along with Fennix C Library. If not, see . */ +#include #include #include diff --git a/Userspace/libc/src/std/math.c b/Userspace/libc/src/std/math.c index a18a99f5..44a2baf0 100644 --- a/Userspace/libc/src/std/math.c +++ b/Userspace/libc/src/std/math.c @@ -20,6 +20,7 @@ #include #include #include +#include #include export int signgam; diff --git a/Userspace/libc/src/std/pthread.c b/Userspace/libc/src/std/pthread.c index 62fef72d..724ea7bd 100644 --- a/Userspace/libc/src/std/pthread.c +++ b/Userspace/libc/src/std/pthread.c @@ -15,6 +15,7 @@ along with Fennix C Library. If not, see . */ +#include #include #include diff --git a/Userspace/libc/src/std/signal.c b/Userspace/libc/src/std/signal.c index 57bd419a..e45ee177 100644 --- a/Userspace/libc/src/std/signal.c +++ b/Userspace/libc/src/std/signal.c @@ -15,13 +15,14 @@ along with Fennix C Library. If not, see . */ +#include #include #include #include export int kill(pid_t pid, int sig) { - return call_kill(pid, sig); + return sysdep(Kill)(pid, sig); } export int killpg(pid_t, int); diff --git a/Userspace/libc/src/std/stdio.c b/Userspace/libc/src/std/stdio.c index 2338e8ee..f1edb812 100644 --- a/Userspace/libc/src/std/stdio.c +++ b/Userspace/libc/src/std/stdio.c @@ -19,7 +19,8 @@ #include #include #include -#include +#include +#include #include "../print/printf.h" struct _IO_FILE *_i_open_files[256]; @@ -74,7 +75,7 @@ export int fclose(FILE *stream) if (stream->buffer) free(stream->buffer); - call_close(stream->fd); + sysdep(Close)(stream->fd); _i_open_files[stream->fd] = NULL; free(stream); return 0; @@ -105,7 +106,7 @@ export int fflush(FILE *stream) { if (stream->buffer_pos > 0) { - ssize_t written = call_write(stream->fd, stream->buffer, stream->buffer_pos); + ssize_t written = sysdep(Write)(stream->fd, stream->buffer, stream->buffer_pos); if (written < 0) { stream->error = 1; @@ -129,7 +130,7 @@ export int fgetc(FILE *stream) if (stream->buffer_pos >= stream->buffer_size) { - int res = call_read(stream->fd, stream->buffer, 4096); + int res = sysdep(Read)(stream->fd, stream->buffer, 4096); if (res <= 0) { if (res == 0) @@ -180,33 +181,33 @@ export FILE *fopen(const char *restrict pathname, const char *restrict mode) mode_t perm = 0; if (strcmp(mode, "r") == 0) - flags = __SYS_O_RDONLY; + flags = O_RDONLY; else if (strcmp(mode, "r+") == 0) - flags = __SYS_O_RDWR; + flags = O_RDWR; else if (strcmp(mode, "w") == 0) { - flags = __SYS_O_WRONLY | __SYS_O_CREAT | __SYS_O_TRUNC; + flags = O_WRONLY | O_CREAT | O_TRUNC; perm = 0644; } else if (strcmp(mode, "w+") == 0) { - flags = __SYS_O_RDWR | __SYS_O_CREAT | __SYS_O_TRUNC; + flags = O_RDWR | O_CREAT | O_TRUNC; perm = 0644; } else if (strcmp(mode, "a") == 0) { - flags = __SYS_O_WRONLY | __SYS_O_CREAT | __SYS_O_APPEND; + flags = O_WRONLY | O_CREAT | O_APPEND; perm = 0644; } else if (strcmp(mode, "a+") == 0) { - flags = __SYS_O_RDWR | __SYS_O_CREAT | __SYS_O_APPEND; + flags = O_RDWR | O_CREAT | O_APPEND; perm = 0644; } else return NULL; - int fd = call_open(pathname, flags, perm); + int fd = sysdep(Open)(pathname, flags, perm); if (fd < 0) return NULL; @@ -274,7 +275,7 @@ export size_t fread(void *restrict ptr, size_t size, size_t nitems, FILE *restri { if (stream->buffer_pos >= stream->buffer_size) { - int res = call_read(stream->fd, stream->buffer, stream->buffer_size); + int res = sysdep(Read)(stream->fd, stream->buffer, stream->buffer_size); if (res <= 0) { if (res == 0) @@ -305,7 +306,7 @@ export int fscanf(FILE *restrict, const char *restrict, ...); export int fseek(FILE *stream, long offset, int whence) { - int res = call_seek(stream->fd, offset, whence); + int res = sysdep(Seek)(stream->fd, offset, whence); if (res < 0) { stream->error = 1; @@ -321,7 +322,7 @@ export int fsetpos(FILE *, const fpos_t *); export long ftell(FILE *stream) { - return call_tell(stream->fd); + return sysdep(Tell)(stream->fd); } export off_t ftello(FILE *); @@ -347,7 +348,7 @@ export size_t fwrite(const void *restrict ptr, size_t size, size_t nitems, FILE if (stream->buffer_pos == stream->buffer_size) { - if (call_write(stream->fd, stream->buffer, stream->buffer_size) != stream->buffer_size) + if (sysdep(Write)(stream->fd, stream->buffer, stream->buffer_size) != stream->buffer_size) { stream->error = 1; break; diff --git a/Userspace/libc/src/std/string.c b/Userspace/libc/src/std/string.c index eba3ff32..abf6d4c1 100644 --- a/Userspace/libc/src/std/string.c +++ b/Userspace/libc/src/std/string.c @@ -17,7 +17,7 @@ #include #include -#include +#include #include #include #include diff --git a/Userspace/libc/src/std/sys/ioctl.c b/Userspace/libc/src/std/sys/ioctl.c index 0aa1911b..05cb9e62 100644 --- a/Userspace/libc/src/std/sys/ioctl.c +++ b/Userspace/libc/src/std/sys/ioctl.c @@ -16,7 +16,7 @@ */ #include -#include +#include #include #include @@ -27,6 +27,6 @@ export int ioctl(int fd, unsigned long op, ...) va_start(args, op); arg = va_arg(args, void *); va_end(args); - int ret = call_ioctl(fd, op, arg); + int ret = sysdep(IOControl)(fd, op, arg); return __check_errno(ret, -1); } diff --git a/Userspace/libc/src/std/sys/mman.c b/Userspace/libc/src/std/sys/mman.c index 29146709..e43b21b2 100644 --- a/Userspace/libc/src/std/sys/mman.c +++ b/Userspace/libc/src/std/sys/mman.c @@ -16,7 +16,7 @@ */ #include -#include +#include #include export int mlock(const void *, size_t); @@ -24,12 +24,12 @@ export int mlockall(int); export void *mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off) { - return (void *)__check_errno((__iptr)call_mmap(addr, len, prot, flags, fildes, off), (__iptr)MAP_FAILED); + return (void *)__check_errno((__iptr)sysdep(MemoryMap)(addr, len, prot, flags, fildes, off), (__iptr)MAP_FAILED); } export int mprotect(void *addr, size_t len, int prot) { - return __check_errno(call_mprotect(addr, len, prot), -1); + return __check_errno(sysdep(MemoryProtect)(addr, len, prot), -1); } export int msync(void *, size_t, int); @@ -38,7 +38,7 @@ export int munlockall(void); export int munmap(void *addr, size_t len) { - return __check_errno(call_munmap(addr, len), -1); + return __check_errno(sysdep(MemoryUnmap)(addr, len), -1); } export int posix_madvise(void *, size_t, int); diff --git a/Userspace/libc/src/std/sys/socket.c b/Userspace/libc/src/std/sys/socket.c index 28cebb53..ce5b358e 100644 --- a/Userspace/libc/src/std/sys/socket.c +++ b/Userspace/libc/src/std/sys/socket.c @@ -17,23 +17,23 @@ #include #include -#include +#include export int accept(int socket, struct sockaddr *restrict address, socklen_t *restrict address_len) { - return __check_errno(call_accept(socket, address, address_len), -1); + return __check_errno(sysdep(Accept)(socket, address, address_len), -1); } export int accept4(int socket, struct sockaddr *restrict address, socklen_t *restrict address_len, int flag); export int bind(int socket, const struct sockaddr *address, socklen_t address_len) { - return __check_errno(call_bind(socket, address, address_len), -1); + return __check_errno(sysdep(Bind)(socket, address, address_len), -1); } export int connect(int socket, const struct sockaddr *address, socklen_t address_len) { - return __check_errno(call_connect(socket, address, address_len), -1); + return __check_errno(sysdep(Connect)(socket, address, address_len), -1); } export int getpeername(int, struct sockaddr *restrict, socklen_t *restrict); @@ -42,7 +42,7 @@ export int getsockopt(int, int, int, void *restrict, socklen_t *restrict); export int listen(int socket, int backlog) { - return __check_errno(call_listen(socket, backlog), -1); + return __check_errno(sysdep(Listen)(socket, backlog), -1); } export ssize_t recv(int, void *, size_t, int); @@ -57,7 +57,7 @@ export int sockatmark(int); export int socket(int domain, int type, int protocol) { - return __check_errno(call_socket(domain, type, protocol), -1); + return __check_errno(sysdep(Socket)(domain, type, protocol), -1); } export int socketpair(int, int, int, int[2]); diff --git a/Userspace/libc/src/std/sys/stat.c b/Userspace/libc/src/std/sys/stat.c index 78fc60ce..b5ae5663 100644 --- a/Userspace/libc/src/std/sys/stat.c +++ b/Userspace/libc/src/std/sys/stat.c @@ -15,6 +15,7 @@ along with Fennix C Library. If not, see . */ +#include #include #include #include @@ -31,7 +32,7 @@ export int fstat(int fildes, struct stat *buf) return -1; } - return __check_errno(call_fstat(fildes, buf), -1); + return __check_errno(sysdep(FStat)(fildes, buf), -1); } export int fstatat(int fd, const char *restrict path, struct stat *restrict buf, int flag) @@ -58,12 +59,12 @@ export int lstat(const char *restrict path, struct stat *restrict buf) return -1; } - return __check_errno(call_lstat(path, buf), -1); + return __check_errno(sysdep(LStat)(path, buf), -1); } export int mkdir(const char *path, mode_t mode) { - return __check_errno(call_mkdir(path, mode), -1); + return __check_errno(sysdep(MakeDirectory)(path, mode), -1); } export int mkdirat(int fd, const char *path, mode_t mode) @@ -85,7 +86,7 @@ export int stat(const char *restrict path, struct stat *restrict buf) return -1; } - return __check_errno(call_stat(path, buf), -1); + return __check_errno(sysdep(Stat)(path, buf), -1); } export mode_t umask(mode_t); diff --git a/Userspace/libc/src/std/sys/utsname.c b/Userspace/libc/src/std/sys/utsname.c index 56dcb12b..cda8df72 100644 --- a/Userspace/libc/src/std/sys/utsname.c +++ b/Userspace/libc/src/std/sys/utsname.c @@ -21,7 +21,7 @@ #include #include #include -#include +#include export int uname(struct utsname *name) { @@ -31,16 +31,8 @@ export int uname(struct utsname *name) return -1; } - struct kutsname kname; - int result = call_uname(&kname); - if (result == 0) - { - strcpy(name->sysname, kname.sysname); - strcpy(name->release, kname.release); - strcpy(name->version, kname.version); - strcpy(name->machine, kname.machine); - } - else + int result = sysdep(UnixName)(name); + if (result != 0) { errno = result; return -1; diff --git a/Userspace/libc/src/std/sys/wait.c b/Userspace/libc/src/std/sys/wait.c index 6b0ef80d..7d10aa2f 100644 --- a/Userspace/libc/src/std/sys/wait.c +++ b/Userspace/libc/src/std/sys/wait.c @@ -16,7 +16,7 @@ */ #include -#include +#include #include #include #include @@ -34,5 +34,5 @@ export int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options) export pid_t waitpid(pid_t pid, int *stat_loc, int options) { - return __check_errno(call_waitpid(pid, stat_loc, options), -1); + return __check_errno(sysdep(WaitProcessID)(pid, stat_loc, options), -1); } diff --git a/Userspace/libc/src/std/termios.c b/Userspace/libc/src/std/termios.c index b49bcf0f..19ccfcb3 100644 --- a/Userspace/libc/src/std/termios.c +++ b/Userspace/libc/src/std/termios.c @@ -15,6 +15,7 @@ along with Fennix C Library. If not, see . */ +#include #include #include #include diff --git a/Userspace/libc/src/std/unistd.c b/Userspace/libc/src/std/unistd.c index 9892924c..721efea8 100644 --- a/Userspace/libc/src/std/unistd.c +++ b/Userspace/libc/src/std/unistd.c @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include export char *optarg; @@ -44,7 +44,7 @@ export int chown(const char *, uid_t, gid_t); export int close(int fildes) { - return __check_errno(call_close(fildes), -1); + return __check_errno(sysdep(Close)(fildes), -1); } export size_t confstr(int, char *, size_t); @@ -130,7 +130,7 @@ export int execv(const char *path, char *const argv[]) export int execve(const char *path, char *const argv[], char *const envp[]) { - return __check_errno(call_execve(path, argv, envp), -1); + return __check_errno(sysdep(Execve)(path, argv, envp), -1); } export int execvp(const char *file, char *const argv[]) @@ -167,7 +167,7 @@ export int fdatasync(int); export pid_t fork(void) { - return __check_errno(call_fork(), -1); + return __check_errno(sysdep(Fork)(), -1); } export long int fpathconf(int, int); @@ -225,12 +225,12 @@ export pid_t getpgrp(void); export pid_t getpid(void) { - return call_getpid(); + return sysdep(GetProcessID)(); } export pid_t getppid(void) { - return call_getppid(); + return sysdep(GetParentProcessID)(); } export pid_t getsid(pid_t); @@ -261,19 +261,19 @@ export int pipe(int[2]); export ssize_t pread(int fildes, void *buf, size_t nbyte, off_t offset) { - return __check_errno(call_pread(fildes, buf, nbyte, offset), -1); + return __check_errno(sysdep(PRead)(fildes, buf, nbyte, offset), -1); } export int pthread_atfork(void (*)(void), void (*)(void), void (*)(void)); export ssize_t pwrite(int fildes, const void *buf, size_t nbyte, off_t offset) { - return __check_errno(call_pwrite(fildes, buf, nbyte, offset), -1); + return __check_errno(sysdep(PWrite)(fildes, buf, nbyte, offset), -1); } export ssize_t read(int fildes, void *buf, size_t nbyte) { - return __check_errno(call_read(fildes, buf, nbyte), -1); + return __check_errno(sysdep(Read)(fildes, buf, nbyte), -1); } export int readlink(const char *, char *, size_t); @@ -324,5 +324,5 @@ export pid_t vfork(void); export ssize_t write(int fildes, const void *buf, size_t nbyte) { - return __check_errno(call_write(fildes, buf, nbyte), -1); + return __check_errno(sysdep(Write)(fildes, buf, nbyte), -1); } diff --git a/Userspace/libc/sysdeps/fennix/generic/dl_start.c b/Userspace/libc/sysdeps/fennix/generic/dl_start.c new file mode 100644 index 00000000..fbdf937e --- /dev/null +++ b/Userspace/libc/sysdeps/fennix/generic/dl_start.c @@ -0,0 +1,58 @@ +/* + This file is part of Fennix C Library. + + Fennix C Library is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix C Library. If not, see . +*/ + +#ifdef FENNIX_DYNAMIC_LOADER +__attribute__((naked, used, no_stack_protector)) void _dl_start() +{ +#if defined(__amd64__) + __asm__( + "xorq %rbp, %rbp\n" /* Clear rbp */ + + "push %rdi\n" + "push %rsi\n" + "push %rdx\n" + "push %rcx\n" + "push %r8\n" + "push %r9\n" + + "call __init_print_buffer\n" /* Call __init_print_buffer */ + "call _dl_preload\n" /* Call _dl_preload */ + "movl %eax, %edi\n" /* Move return value to edi */ + "cmp $0, %edi\n" /* Check if return value is 0 */ + "jne _exit\n" /* If not, jump to _exit */ + + "pop %r9\n" + "pop %r8\n" + "pop %rcx\n" + "pop %rdx\n" + "pop %rsi\n" + "pop %rdi\n" + + "call main\n" /* Call _dl_main */ + "movl %eax, %edi\n" /* Move return value to edi */ + "call _exit\n"); /* Call _exit */ +#elif defined(__i386__) +#warning "i386 _start not implemented" +#elif defined(__arm__) +#warning "arm _start not implemented" +#elif defined(__aarch64__) +#warning "aarch64 _start not implemented" +#else +#error "Unsupported architecture" +#endif +} +#endif diff --git a/Userspace/libc/src/syscall_check.cpp b/Userspace/libc/sysdeps/fennix/generic/syscall_check.cpp similarity index 95% rename from Userspace/libc/src/syscall_check.cpp rename to Userspace/libc/sysdeps/fennix/generic/syscall_check.cpp index 378b3392..4e464eab 100644 --- a/Userspace/libc/src/syscall_check.cpp +++ b/Userspace/libc/sysdeps/fennix/generic/syscall_check.cpp @@ -15,7 +15,7 @@ along with Fennix C Library. If not, see . */ -#include +#include #include #include #include @@ -38,7 +38,7 @@ static_assert(__SYS_W_OK == W_OK); static_assert(__SYS_X_OK == X_OK); static_assert(sizeof(__SYS_clockid_t) == sizeof(clockid_t)); -// static_assert(sizeof(__SYS_socklen_t) == sizeof(socklen_t)); +static_assert(sizeof(__SYS_socklen_t) == sizeof(socklen_t)); static_assert(__SYS_SEEK_SET == SEEK_SET); static_assert(__SYS_SEEK_CUR == SEEK_CUR); diff --git a/Userspace/libc/sysdeps/fennix/generic/syscalls.c b/Userspace/libc/sysdeps/fennix/generic/syscalls.c new file mode 100644 index 00000000..cf03d41a --- /dev/null +++ b/Userspace/libc/sysdeps/fennix/generic/syscalls.c @@ -0,0 +1,191 @@ +/* + This file is part of Fennix C Library. + + Fennix C Library is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix C Library. If not, see . +*/ + +#include +#include +#include + +void sysdep(Exit)(int Status) +{ + call_exit(Status); +} + +int sysdep(Accept)(int Socket, struct sockaddr *restrict Address, socklen_t *restrict AddressLength) +{ + return call_accept(Socket, Address, AddressLength); +} + +int sysdep(Bind)(int Socket, const struct sockaddr *Address, socklen_t AddressLength) +{ + return call_bind(Socket, Address, AddressLength); +} + +int sysdep(Connect)(int Socket, const struct sockaddr *Address, socklen_t AddressLength) +{ + return call_connect(Socket, Address, AddressLength); +} + +int sysdep(Listen)(int Socket, int Backlog) +{ + return call_listen(Socket, Backlog); +} + +int sysdep(Socket)(int Domain, int Type, int Protocol) +{ + return call_socket(Domain, Type, Protocol); +} + +int sysdep(UnixName)(struct utsname *Name) +{ + struct kutsname kname; + int result = call_uname(&kname); + if (result == 0) + { + strcpy(Name->sysname, kname.sysname); + strcpy(Name->release, kname.release); + strcpy(Name->version, kname.version); + strcpy(Name->machine, kname.machine); + return 0; + } + + return result; +} + +int sysdep(WaitProcessID)(pid_t ProcessID, int *Status, int Options) +{ + return call_waitpid(ProcessID, Status, Options); +} + +int sysdep(IOControl)(int Descriptor, unsigned long Operation, void *Argument) +{ + return call_ioctl(Descriptor, Operation, Argument); +} + +void *sysdep(MemoryMap)(void *Address, size_t Length, int Protection, int Flags, int Descriptor, off_t Offset) +{ + return (void *)call_mmap(Address, Length, Protection, Flags, Descriptor, Offset); +} + +int sysdep(MemoryUnmap)(void *Address, size_t Length) +{ + return call_munmap(Address, Length); +} + +int sysdep(MemoryProtect)(void *Address, size_t Length, int Protection) +{ + return call_mprotect(Address, Length, Protection); +} + +int sysdep(Fork)(void) +{ + return call_fork(); +} + +int sysdep(Read)(int Descriptor, void *Buffer, size_t Size) +{ + return call_read(Descriptor, Buffer, Size); +} + +int sysdep(Write)(int Descriptor, const void *Buffer, size_t Size) +{ + return call_write(Descriptor, Buffer, Size); +} + +int sysdep(PRead)(int Descriptor, void *Buffer, size_t Size, off_t Offset) +{ + return call_pread(Descriptor, Buffer, Size, Offset); +} + +int sysdep(PWrite)(int Descriptor, const void *Buffer, size_t Size, off_t Offset) +{ + return call_pwrite(Descriptor, Buffer, Size, Offset); +} + +int sysdep(Open)(const char *Pathname, int Flags, mode_t Mode) +{ + return call_open(Pathname, Flags, Mode); +} + +int sysdep(Close)(int Descriptor) +{ + return call_close(Descriptor); +} + +int sysdep(Access)(const char *Pathname, int Mode) +{ + return call_access(Pathname, Mode); +} + +int sysdep(Tell)(int Descriptor) +{ + return call_tell(Descriptor); +} + +int sysdep(Seek)(int Descriptor, off_t Offset, int Whence) +{ + return call_seek(Descriptor, Offset, Whence); +} + +pid_t sysdep(GetProcessID)(void) +{ + return call_getpid(); +} + +pid_t sysdep(GetParentProcessID)(void) +{ + return call_getppid(); +} + +int sysdep(Execve)(const char *Pathname, char *const *Argv, char *const *Envp) +{ + return call_execve(Pathname, Argv, Envp); +} + +int sysdep(Kill)(pid_t ProcessID, int Signal) +{ + return call_kill(ProcessID, Signal); +} + +int sysdep(Stat)(const char *Pathname, struct stat *Statbuf) +{ + return call_stat(Pathname, Statbuf); +} + +int sysdep(FStat)(int Descriptor, struct stat *Statbuf) +{ + return call_fstat(Descriptor, Statbuf); +} + +int sysdep(LStat)(const char *Pathname, struct stat *Statbuf) +{ + return call_lstat(Pathname, Statbuf); +} + +int sysdep(Truncate)(const char *Pathname, off_t Length) +{ + return call_truncate(Pathname, Length); +} + +int sysdep(MakeDirectory)(const char *Pathname, mode_t Mode) +{ + return call_mkdir(Pathname, Mode); +} + +int sysdep(ProcessControl)(unsigned long Option, unsigned long Arg1, unsigned long Arg2, unsigned long Arg3, unsigned long Arg4) +{ + return call_prctl(Option, Arg1, Arg2, Arg3, Arg4); +} diff --git a/Userspace/libc/src/tls.c b/Userspace/libc/sysdeps/fennix/generic/tls.c similarity index 86% rename from Userspace/libc/src/tls.c rename to Userspace/libc/sysdeps/fennix/generic/tls.c index 59d52ecb..e81c0be5 100644 --- a/Userspace/libc/src/tls.c +++ b/Userspace/libc/sysdeps/fennix/generic/tls.c @@ -15,13 +15,14 @@ along with Fennix C Library. If not, see . */ -#include +#include +#include #include +#include #include #include -#include - +#ifndef FENNIX_DYNAMIC_LOADER export __attribute__((naked, used, no_stack_protector)) void *__tls_get_addr(void *__data) { #warning "__tls_get_addr not implemented" @@ -34,11 +35,12 @@ int __init_pthread(void) { __pthread *ptr = (__pthread *)call_mmap(0, 0x1000, - __SYS_PROT_READ | __SYS_PROT_WRITE, - __SYS_MAP_ANONYMOUS | __SYS_MAP_PRIVATE, + PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); call_prctl(__SYS_SET_FS, ptr, 0, 0, 0); ptr->Self = ptr; ptr->CurrentError = 0; return 0; } +#endif diff --git a/Userspace/libc/workspace_test.c b/Userspace/libc/workspace_test.c new file mode 100644 index 00000000..9ba42c1e --- /dev/null +++ b/Userspace/libc/workspace_test.c @@ -0,0 +1,22 @@ +/* + This file is part of Fennix C Library. + + Fennix C Library is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix C Library. If not, see . +*/ + +#ifndef __fennix__ +#error "Macro __fennix__ is not defined." +#endif + +int main() { return 0; } diff --git a/Userspace/libs/Makefile b/Userspace/libs/Makefile index 6c718158..2675176a 100644 --- a/Userspace/libs/Makefile +++ b/Userspace/libs/Makefile @@ -1,12 +1,8 @@ build: cp -a $(CURDIR)/include/. $(WORKSPACE_DIR)/out/include make -C libgcc build - make -C libm build - make -C libstdc++ build make -C libexample build clean: make -C libgcc clean - make -C libm clean - make -C libstdc++ clean make -C libexample clean diff --git a/Userspace/libs/libexample/example.c b/Userspace/libs/libexample/example.c index f1a40ac7..9a6dedac 100644 --- a/Userspace/libs/libexample/example.c +++ b/Userspace/libs/libexample/example.c @@ -15,7 +15,7 @@ along with Fennix Userspace. If not, see . */ -#include +#include export int foo() { diff --git a/Userspace/libs/libm/Makefile b/Userspace/libs/libm/Makefile deleted file mode 100644 index eddae0a7..00000000 --- a/Userspace/libs/libm/Makefile +++ /dev/null @@ -1,48 +0,0 @@ -default: - $(error Do not run this Makefile directly!) - -DYNAMIC_NAME := $(notdir $(shell pwd)).so -STATIC_NAME := $(notdir $(shell pwd)).a - -OUTPUT_DIR=$(WORKSPACE_DIR)/out/lib/ -SYSROOT = --sysroot=$(WORKSPACE_DIR)/out/ - -S_SOURCES = $(shell find ./ -type f -name '*.S') -C_SOURCES = $(shell find ./ -type f -name '*.c') -CXX_SOURCES = $(shell find ./ -type f -name '*.cpp') -OBJ = ${S_SOURCES:.S=.o} ${C_SOURCES:.c=.o} ${CXX_SOURCES:.cpp=.o} - -CFLAGS := -fvisibility=hidden -fPIC -I../include -I$(WORKSPACE_DIR)/out/include -DLIBC_GIT_COMMIT='"$(shell git rev-parse HEAD)"' - -ifeq ($(DEBUG), 1) - CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -endif - -build: $(DYNAMIC_NAME) $(STATIC_NAME) - -.PHONY: $(DYNAMIC_NAME) $(STATIC_NAME) - -$(DYNAMIC_NAME): $(OBJ) - $(info Linking $@) - $(CC) -nostdlib -shared -fPIC -fPIE -Wl,-soname,$(DYNAMIC_NAME) $(SYSROOT) $(OBJ) -o $(DYNAMIC_NAME) - cp $(DYNAMIC_NAME) $(OUTPUT_DIR)$(DYNAMIC_NAME) - -$(STATIC_NAME): $(OBJ) - $(info Linking $@) - $(AR) -rcs $(STATIC_NAME) $(OBJ) - cp $(STATIC_NAME) $(OUTPUT_DIR)$(STATIC_NAME) - -%.o: %.c - $(info Compiling $<) - $(CC) $(CFLAGS) -std=c17 -c $< -o $@ - -%.o: %.cpp - $(info Compiling $<) - $(CC) $(CFLAGS) -std=c++20 -c $< -o $@ - -%.o: %.S - $(info Compiling $<) - $(AS) -c $< -o $@ - -clean: - rm -f $(OBJ) $(DYNAMIC_NAME) $(STATIC_NAME) diff --git a/Userspace/libs/libstdc++/Makefile b/Userspace/libs/libstdc++/Makefile deleted file mode 100644 index eddae0a7..00000000 --- a/Userspace/libs/libstdc++/Makefile +++ /dev/null @@ -1,48 +0,0 @@ -default: - $(error Do not run this Makefile directly!) - -DYNAMIC_NAME := $(notdir $(shell pwd)).so -STATIC_NAME := $(notdir $(shell pwd)).a - -OUTPUT_DIR=$(WORKSPACE_DIR)/out/lib/ -SYSROOT = --sysroot=$(WORKSPACE_DIR)/out/ - -S_SOURCES = $(shell find ./ -type f -name '*.S') -C_SOURCES = $(shell find ./ -type f -name '*.c') -CXX_SOURCES = $(shell find ./ -type f -name '*.cpp') -OBJ = ${S_SOURCES:.S=.o} ${C_SOURCES:.c=.o} ${CXX_SOURCES:.cpp=.o} - -CFLAGS := -fvisibility=hidden -fPIC -I../include -I$(WORKSPACE_DIR)/out/include -DLIBC_GIT_COMMIT='"$(shell git rev-parse HEAD)"' - -ifeq ($(DEBUG), 1) - CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -endif - -build: $(DYNAMIC_NAME) $(STATIC_NAME) - -.PHONY: $(DYNAMIC_NAME) $(STATIC_NAME) - -$(DYNAMIC_NAME): $(OBJ) - $(info Linking $@) - $(CC) -nostdlib -shared -fPIC -fPIE -Wl,-soname,$(DYNAMIC_NAME) $(SYSROOT) $(OBJ) -o $(DYNAMIC_NAME) - cp $(DYNAMIC_NAME) $(OUTPUT_DIR)$(DYNAMIC_NAME) - -$(STATIC_NAME): $(OBJ) - $(info Linking $@) - $(AR) -rcs $(STATIC_NAME) $(OBJ) - cp $(STATIC_NAME) $(OUTPUT_DIR)$(STATIC_NAME) - -%.o: %.c - $(info Compiling $<) - $(CC) $(CFLAGS) -std=c17 -c $< -o $@ - -%.o: %.cpp - $(info Compiling $<) - $(CC) $(CFLAGS) -std=c++20 -c $< -o $@ - -%.o: %.S - $(info Compiling $<) - $(AS) -c $< -o $@ - -clean: - rm -f $(OBJ) $(DYNAMIC_NAME) $(STATIC_NAME)