mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 15:17:36 +00:00
Libraries: Move to Userland/Libraries/
This commit is contained in:
parent
dc28c07fa5
commit
13d7c09125
1857 changed files with 266 additions and 274 deletions
90
Userland/Libraries/LibC/CMakeLists.txt
Normal file
90
Userland/Libraries/LibC/CMakeLists.txt
Normal file
|
@ -0,0 +1,90 @@
|
|||
set(LIBC_SOURCES
|
||||
arpa/inet.cpp
|
||||
assert.cpp
|
||||
ctype.cpp
|
||||
cxxabi.cpp
|
||||
dirent.cpp
|
||||
dlfcn.cpp
|
||||
fcntl.cpp
|
||||
getopt.cpp
|
||||
grp.cpp
|
||||
ioctl.cpp
|
||||
libcinit.cpp
|
||||
libgen.cpp
|
||||
locale.cpp
|
||||
malloc.cpp
|
||||
mman.cpp
|
||||
mntent.cpp
|
||||
netdb.cpp
|
||||
poll.cpp
|
||||
pwd.cpp
|
||||
qsort.cpp
|
||||
scanf.cpp
|
||||
sched.cpp
|
||||
serenity.cpp
|
||||
setjmp.S
|
||||
signal.cpp
|
||||
spawn.cpp
|
||||
stat.cpp
|
||||
stdio.cpp
|
||||
stdlib.cpp
|
||||
string.cpp
|
||||
strings.cpp
|
||||
syslog.cpp
|
||||
sys/prctl.cpp
|
||||
sys/ptrace.cpp
|
||||
sys/select.cpp
|
||||
sys/socket.cpp
|
||||
sys/uio.cpp
|
||||
sys/wait.cpp
|
||||
termcap.cpp
|
||||
termios.cpp
|
||||
time.cpp
|
||||
times.cpp
|
||||
ulimit.cpp
|
||||
unistd.cpp
|
||||
utime.cpp
|
||||
utsname.cpp
|
||||
wchar.cpp
|
||||
)
|
||||
|
||||
file(GLOB AK_SOURCES CONFIGURE_DEPENDS "../../../AK/*.cpp")
|
||||
file(GLOB ELF_SOURCES CONFIGURE_DEPENDS "../LibELF/*.cpp")
|
||||
set(ELF_SOURCES ${ELF_SOURCES} ../LibELF/Arch/i386/plt_trampoline.S)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unknown-warning-option -DSERENITY_LIBC_BUILD")
|
||||
|
||||
find_program(INSTALL_COMMAND ginstall)
|
||||
if(NOT INSTALL_COMMAND)
|
||||
set(INSTALL_COMMAND install)
|
||||
endif()
|
||||
|
||||
add_library(crt0 STATIC crt0.cpp)
|
||||
add_custom_command(
|
||||
TARGET crt0
|
||||
COMMAND ${INSTALL_COMMAND} -D $<TARGET_OBJECTS:crt0> ${CMAKE_INSTALL_PREFIX}/usr/lib/crt0.o
|
||||
)
|
||||
add_library(crt0_shared STATIC crt0_shared.cpp)
|
||||
add_custom_command(
|
||||
TARGET crt0_shared
|
||||
COMMAND ${INSTALL_COMMAND} -D $<TARGET_OBJECTS:crt0_shared> ${CMAKE_INSTALL_PREFIX}/usr/lib/crt0_shared.o
|
||||
)
|
||||
|
||||
set_source_files_properties (ssp.cpp PROPERTIES COMPILE_FLAGS
|
||||
"-fno-stack-protector")
|
||||
add_library(ssp STATIC ssp.cpp)
|
||||
add_custom_command(
|
||||
TARGET ssp
|
||||
COMMAND ${INSTALL_COMMAND} -D $<TARGET_OBJECTS:ssp> ${CMAKE_INSTALL_PREFIX}/usr/lib/ssp.o
|
||||
)
|
||||
|
||||
set(SOURCES ${LIBC_SOURCES} ${AK_SOURCES} ${ELF_SOURCES})
|
||||
|
||||
serenity_libc_static(LibCStatic c)
|
||||
target_link_libraries(LibCStatic crt0 ssp)
|
||||
add_dependencies(LibCStatic LibM)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libstdc++")
|
||||
serenity_libc(LibC c)
|
||||
target_link_libraries(LibC crt0 ssp)
|
||||
add_dependencies(LibC LibM)
|
29
Userland/Libraries/LibC/alloca.h
Normal file
29
Userland/Libraries/LibC/alloca.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define alloca __builtin_alloca
|
92
Userland/Libraries/LibC/arpa/inet.cpp
Normal file
92
Userland/Libraries/LibC/arpa/inet.cpp
Normal file
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdio.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
const char* inet_ntop(int af, const void* src, char* dst, socklen_t len)
|
||||
{
|
||||
if (af != AF_INET) {
|
||||
errno = EAFNOSUPPORT;
|
||||
return nullptr;
|
||||
}
|
||||
auto* bytes = (const unsigned char*)src;
|
||||
snprintf(dst, len, "%u.%u.%u.%u", bytes[0], bytes[1], bytes[2], bytes[3]);
|
||||
return (const char*)dst;
|
||||
}
|
||||
|
||||
int inet_pton(int af, const char* src, void* dst)
|
||||
{
|
||||
if (af != AF_INET) {
|
||||
errno = EAFNOSUPPORT;
|
||||
return -1;
|
||||
}
|
||||
unsigned a;
|
||||
unsigned b;
|
||||
unsigned c;
|
||||
unsigned d;
|
||||
int count = sscanf(src, "%u.%u.%u.%u", &a, &b, &c, &d);
|
||||
if (count != 4) {
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
union {
|
||||
struct {
|
||||
uint8_t a;
|
||||
uint8_t b;
|
||||
uint8_t c;
|
||||
uint8_t d;
|
||||
};
|
||||
uint32_t l;
|
||||
} u;
|
||||
u.a = a;
|
||||
u.b = b;
|
||||
u.c = c;
|
||||
u.d = d;
|
||||
*(uint32_t*)dst = u.l;
|
||||
return 1;
|
||||
}
|
||||
|
||||
in_addr_t inet_addr(const char* str)
|
||||
{
|
||||
in_addr_t tmp {};
|
||||
int rc = inet_pton(AF_INET, str, &tmp);
|
||||
if (rc < 0)
|
||||
return INADDR_NONE;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
char* inet_ntoa(struct in_addr in)
|
||||
{
|
||||
static char buffer[32];
|
||||
inet_ntop(AF_INET, &in.s_addr, buffer, sizeof(buffer));
|
||||
return buffer;
|
||||
}
|
||||
}
|
75
Userland/Libraries/LibC/arpa/inet.h
Normal file
75
Userland/Libraries/LibC/arpa/inet.h
Normal file
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <endian.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
#define INET_ADDRSTRLEN 16
|
||||
|
||||
const char* inet_ntop(int af, const void* src, char* dst, socklen_t);
|
||||
int inet_pton(int af, const char* src, void* dst);
|
||||
|
||||
static inline int inet_aton(const char* cp, struct in_addr* inp)
|
||||
{
|
||||
return inet_pton(AF_INET, cp, inp);
|
||||
}
|
||||
|
||||
char* inet_ntoa(struct in_addr);
|
||||
|
||||
inline uint16_t htons(uint16_t value)
|
||||
{
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
return __builtin_bswap16(value);
|
||||
#else
|
||||
return value;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline uint16_t ntohs(uint16_t value)
|
||||
{
|
||||
return htons(value);
|
||||
}
|
||||
|
||||
inline uint32_t htonl(uint32_t value)
|
||||
{
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
return __builtin_bswap32(value);
|
||||
#else
|
||||
return value;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline uint32_t ntohl(uint32_t value)
|
||||
{
|
||||
return htonl(value);
|
||||
}
|
||||
|
||||
__END_DECLS
|
54
Userland/Libraries/LibC/assert.cpp
Normal file
54
Userland/Libraries/LibC/assert.cpp
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <Kernel/API/Syscall.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/internals.h>
|
||||
#include <unistd.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
extern bool __stdio_is_initialized;
|
||||
#ifdef DEBUG
|
||||
void __assertion_failed(const char* msg)
|
||||
{
|
||||
dbgprintf("USERSPACE(%d) ASSERTION FAILED: %s\n", getpid(), msg);
|
||||
if (__stdio_is_initialized)
|
||||
fprintf(stderr, "ASSERTION FAILED: %s\n", msg);
|
||||
|
||||
Syscall::SC_set_coredump_metadata_params params {
|
||||
{ "assertion", strlen("assertion") },
|
||||
{ msg, strlen(msg) },
|
||||
};
|
||||
syscall(SC_set_coredump_metadata, ¶ms);
|
||||
syscall(SC_abort);
|
||||
for (;;) { }
|
||||
}
|
||||
#endif
|
||||
}
|
56
Userland/Libraries/LibC/assert.h
Normal file
56
Userland/Libraries/LibC/assert.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
#ifdef DEBUG
|
||||
__attribute__((noreturn)) void __assertion_failed(const char* msg);
|
||||
# define __stringify_helper(x) # x
|
||||
# define __stringify(x) __stringify_helper(x)
|
||||
# define assert(expr) \
|
||||
do { \
|
||||
if (__builtin_expect(!(expr), 0)) \
|
||||
__assertion_failed(#expr "\n" __FILE__ ":" __stringify(__LINE__)); \
|
||||
} while (0)
|
||||
# define ASSERT_NOT_REACHED() assert(false)
|
||||
#else
|
||||
# define assert(expr) ((void)(0))
|
||||
# define ASSERT_NOT_REACHED() CRASH()
|
||||
#endif
|
||||
|
||||
#define CRASH() \
|
||||
do { \
|
||||
asm volatile("ud2"); \
|
||||
} while (0)
|
||||
#define ASSERT assert
|
||||
#define RELEASE_ASSERT assert
|
||||
#define TODO ASSERT_NOT_REACHED
|
||||
|
||||
__END_DECLS
|
38
Userland/Libraries/LibC/bits/FILE.h
Normal file
38
Userland/Libraries/LibC/bits/FILE.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Jesse Buhagiar <jooster669@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#define BUFSIZ 1024
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
typedef struct FILE FILE;
|
||||
|
||||
__END_DECLS
|
65
Userland/Libraries/LibC/bits/posix1_lim.h
Normal file
65
Userland/Libraries/LibC/bits/posix1_lim.h
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright (c) 2020, the SerenityOS developers.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define _POSIX_AIO_LISTIO_MAX 2 /* The number of I/O operations that can be specified in a list I/O call. */
|
||||
#define _POSIX_AIO_MAX 1 /* The number of outstanding asynchronous I/O operations. */
|
||||
#define _POSIX_ARG_MAX 4096 /* Maximum length of argument to the exec functions including environment data. */
|
||||
#define _POSIX_CHILD_MAX 25 /* Maximum number of simultaneous processes per real user ID. */
|
||||
#define _POSIX_DELAYTIMER_MAX 32 /* The number of timer expiration overruns. */
|
||||
#define _POSIX_HOST_NAME_MAX 255 /* Maximum length of a host name (not including the terminating null) as returned from the gethostname() function. */
|
||||
#define _POSIX_LINK_MAX 8 /* Maximum number of links to a single file. */
|
||||
#define _POSIX_LOGIN_NAME_MAX 9 /* The size of the storage required for a login name, in bytes, including the terminating null. */
|
||||
#define _POSIX_MAX_CANON 255 /* Maximum number of bytes in a terminal canonical input queue. */
|
||||
#define _POSIX_MAX_INPUT 255 /* Maximum number of bytes allowed in a terminal input queue. */
|
||||
#define _POSIX_MQ_OPEN_MAX 8 /* The number of message queues that can be open for a single process.) */
|
||||
#define _POSIX_MQ_PRIO_MAX 32 /* The maximum number of message priorities supported by the implementation. */
|
||||
#define _POSIX_NAME_MAX 14 /* Maximum number of bytes in a filename (not including terminating null). */
|
||||
#define _POSIX_NGROUPS_MAX 8 /* Maximum number of simultaneous supplementary group IDs per process. */
|
||||
#define _POSIX_OPEN_MAX 20 /* Maximum number of files that one process can have open at any one time. */
|
||||
#define _POSIX_PATH_MAX 256 /* Maximum number of bytes in a pathname. */
|
||||
#define _POSIX_PIPE_BUF 512 /* Maximum number of bytes that is guaranteed to be atomic when writing to a pipe. */
|
||||
#define _POSIX_RE_DUP_MAX 255 /* The number of repeated occurrences of a BRE permitted by the regexec() and regcomp() functions when using the interval notation #define \(m,n\}; see BREs Matching Multiple Characters. */
|
||||
#define _POSIX_RTSIG_MAX 8 /* The number of realtime signal numbers reserved for application use. */
|
||||
#define _POSIX_SEM_NSEMS_MAX 256 /* The number of semaphores that a process may have. */
|
||||
#define _POSIX_SEM_VALUE_MAX 32767 /* The maximum value a semaphore may have. */
|
||||
#define _POSIX_SIGQUEUE_MAX 32 /* The number of queued signals that a process may send and have pending at the receiver(s) at any time. */
|
||||
#define _POSIX_SSIZE_MAX 32767 /* The value that can be stored in an object of type ssize_t. */
|
||||
#define _POSIX_SS_REPL_MAX 4 /* The number of replenishment operations that may be simultaneously pending for a particular sporadic server scheduler. */
|
||||
#define _POSIX_STREAM_MAX 8 /* The number of streams that one process can have open at one time. */
|
||||
#define _POSIX_SYMLINK_MAX 255 /* The number of bytes in a symbolic link. */
|
||||
#define _POSIX_SYMLOOP_MAX 8 /* The number of symbolic links that can be traversed in the resolution of a pathname in the absence of a loop. */
|
||||
#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4 /* The number of attempts made to destroy a thread's thread-specific data values on thread exit. */
|
||||
#define _POSIX_THREAD_KEYS_MAX 128 /* The number of data keys per process. */
|
||||
#define _POSIX_THREAD_THREADS_MAX 64 /* The number of threads per process. */
|
||||
#define _POSIX_TIMER_MAX 32 /* The per-process number of timers. */
|
||||
#define _POSIX_TRACE_EVENT_NAME_MAX 30 /* The length in bytes of a trace event name. */
|
||||
#define _POSIX_TRACE_NAME_MAX 8 /* The length in bytes of a trace generation version string or a trace stream name. */
|
||||
#define _POSIX_TRACE_SYS_MAX 8 /* The number of trace streams that may simultaneously exist in the system. */
|
||||
#define _POSIX_TRACE_USER_EVENT_MAX 32 /* The number of user trace event type identifiers that may simultaneously exist in a traced process, including the predefined user trace event POSIX_TRACE_UNNAMED_USER_EVENT. */
|
||||
#define _POSIX_TTY_NAME_MAX 9 /* The size of the storage required for a terminal device name, in bytes, including the terminating null. */
|
||||
#define _POSIX_TZNAME_MAX 6 /* Maximum number of bytes supported for the name of a timezone (not of the TZ variable). */
|
144
Userland/Libraries/LibC/bits/stdint.h
Normal file
144
Userland/Libraries/LibC/bits/stdint.h
Normal file
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
typedef __UINT64_TYPE__ uint64_t;
|
||||
typedef __UINT32_TYPE__ uint32_t;
|
||||
typedef __UINT16_TYPE__ uint16_t;
|
||||
typedef __UINT8_TYPE__ uint8_t;
|
||||
|
||||
typedef __INT64_TYPE__ int64_t;
|
||||
typedef __INT32_TYPE__ int32_t;
|
||||
typedef __INT16_TYPE__ int16_t;
|
||||
typedef __INT8_TYPE__ int8_t;
|
||||
|
||||
typedef __UINT_FAST8_TYPE__ uint_fast8_t;
|
||||
typedef __UINT_FAST16_TYPE__ uint_fast16_t;
|
||||
typedef __UINT_FAST32_TYPE__ uint_fast32_t;
|
||||
typedef __UINT_FAST64_TYPE__ uint_fast64_t;
|
||||
|
||||
typedef __INT_FAST8_TYPE__ int_fast8_t;
|
||||
typedef __INT_FAST16_TYPE__ int_fast16_t;
|
||||
typedef __INT_FAST32_TYPE__ int_fast32_t;
|
||||
typedef __INT_FAST64_TYPE__ int_fast64_t;
|
||||
|
||||
typedef __UINT_LEAST8_TYPE__ uint_least8_t;
|
||||
typedef __UINT_LEAST16_TYPE__ uint_least16_t;
|
||||
typedef __UINT_LEAST32_TYPE__ uint_least32_t;
|
||||
typedef __UINT_LEAST64_TYPE__ uint_least64_t;
|
||||
|
||||
typedef __INT_LEAST8_TYPE__ int_least8_t;
|
||||
typedef __INT_LEAST16_TYPE__ int_least16_t;
|
||||
typedef __INT_LEAST32_TYPE__ int_least32_t;
|
||||
typedef __INT_LEAST64_TYPE__ int_least64_t;
|
||||
|
||||
#define __int8_t_defined 1
|
||||
#define __uint8_t_defined 1
|
||||
#define __int16_t_defined 1
|
||||
#define __uint16_t_defined 1
|
||||
#define __int32_t_defined 1
|
||||
#define __uint32_t_defined 1
|
||||
#define __int64_t_defined 1
|
||||
#define __uint64_t_defined 1
|
||||
|
||||
typedef __UINTPTR_TYPE__ uintptr_t;
|
||||
typedef __INTPTR_TYPE__ intptr_t;
|
||||
|
||||
typedef __UINTMAX_TYPE__ uintmax_t;
|
||||
#define UINTMAX_MAX __UINTMAX_MAX__
|
||||
#define UINTMAX_MIN __UINTMAX_MIN__
|
||||
|
||||
typedef __INTMAX_TYPE__ intmax_t;
|
||||
#define INTMAX_MAX __INTMAX_MAX__
|
||||
#define INTMAX_MIN (-INTMAX_MAX - 1)
|
||||
|
||||
#define INT8_MIN (-128)
|
||||
#define INT16_MIN (-32767 - 1)
|
||||
#define INT32_MIN (-2147483647 - 1)
|
||||
#define INT64_MIN (-9223372036854775807LL - 1LL)
|
||||
#define INT8_MAX (127)
|
||||
#define INT16_MAX (32767)
|
||||
#define INT32_MAX (2147483647)
|
||||
#define INT64_MAX (9223372036854775807LL)
|
||||
#define UINT8_MAX (255)
|
||||
#define UINT16_MAX (65535)
|
||||
#define UINT32_MAX (4294967295U)
|
||||
#define UINT64_MAX (18446744073709551615ULL)
|
||||
|
||||
#define INTPTR_MAX INT32_MAX
|
||||
#define INTPTR_MIN INT32_MIN
|
||||
#define UINTPTR_MAX UINT32_MAX
|
||||
|
||||
#define INT_FAST8_MIN INT8_MIN
|
||||
#define INT_FAST16_MIN INT16_MIN
|
||||
#define INT_FAST32_MIN INT32_MIN
|
||||
#define INT_FAST64_MIN INT64_MIN
|
||||
|
||||
#define INT_FAST8_MAX INT8_MAX
|
||||
#define INT_FAST16_MAX INT16_MAX
|
||||
#define INT_FAST32_MAX INT32_MAX
|
||||
#define INT_FAST64_MAX INT64_MAX
|
||||
|
||||
#define UINT_FAST8_MAX UINT8_MAX
|
||||
#define UINT_FAST16_MAX UINT16_MAX
|
||||
#define UINT_FAST32_MAX UINT32_MAX
|
||||
#define UINT_FAST64_MAX UINT64_MAX
|
||||
|
||||
#define INT_LEAST8_MIN INT8_MIN
|
||||
#define INT_LEAST16_MIN INT16_MIN
|
||||
#define INT_LEAST32_MIN INT32_MIN
|
||||
#define INT_LEAST64_MIN INT64_MIN
|
||||
|
||||
#define INT_LEAST8_MAX INT8_MAX
|
||||
#define INT_LEAST16_MAX INT16_MAX
|
||||
#define INT_LEAST32_MAX INT32_MAX
|
||||
#define INT_LEAST64_MAX INT64_MAX
|
||||
|
||||
#define UINT_LEAST8_MAX UINT8_MAX
|
||||
#define UINT_LEAST16_MAX UINT16_MAX
|
||||
#define UINT_LEAST32_MAX UINT32_MAX
|
||||
#define UINT_LEAST64_MAX UINT64_MAX
|
||||
|
||||
#define INT8_C(x) x
|
||||
#define UINT8_C(x) x
|
||||
|
||||
#define INT16_C(x) x
|
||||
#define UINT16_C(x) x
|
||||
|
||||
#define INT32_C(x) x
|
||||
#define UINT32_C(x) x
|
||||
|
||||
#define INT64_C(x) x##LL
|
||||
#define UINT64_C(x) x##ULL
|
||||
|
||||
#define SIZE_MAX ((size_t)-1)
|
||||
|
||||
__END_DECLS
|
37
Userland/Libraries/LibC/byteswap.h
Normal file
37
Userland/Libraries/LibC/byteswap.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (c) 2020, the SerenityOS developers
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
#define bswap_16(x) (__builtin_bswap16(x))
|
||||
#define bswap_32(x) (__builtin_bswap32(x))
|
||||
#define bswap_64(x) (__builtin_bswap64(x))
|
||||
|
||||
__END_DECLS
|
76
Userland/Libraries/LibC/crt0.cpp
Normal file
76
Userland/Libraries/LibC/crt0.cpp
Normal file
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <AK/Types.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/internals.h>
|
||||
#include <unistd.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
extern u32 __stack_chk_guard;
|
||||
|
||||
int main(int, char**, char**);
|
||||
|
||||
// Tell the compiler that this may be called from somewhere else.
|
||||
int _start(int argc, char** argv, char** env);
|
||||
|
||||
int _start(int argc, char** argv, char** env)
|
||||
{
|
||||
u32 original_stack_chk = __stack_chk_guard;
|
||||
arc4random_buf(&__stack_chk_guard, sizeof(__stack_chk_guard));
|
||||
|
||||
if (__stack_chk_guard == 0)
|
||||
__stack_chk_guard = original_stack_chk;
|
||||
|
||||
environ = env;
|
||||
__environ_is_malloced = false;
|
||||
|
||||
__libc_init();
|
||||
|
||||
_init();
|
||||
|
||||
extern void (*__init_array_start[])(int, char**, char**) __attribute__((visibility("hidden")));
|
||||
extern void (*__init_array_end[])(int, char**, char**) __attribute__((visibility("hidden")));
|
||||
|
||||
const size_t size = __init_array_end - __init_array_start;
|
||||
for (size_t i = 0; i < size; i++)
|
||||
(*__init_array_start[i])(argc, argv, env);
|
||||
|
||||
int status = main(argc, argv, environ);
|
||||
|
||||
exit(status);
|
||||
|
||||
// We should never get here, but if we ever do, make sure to
|
||||
// restore the stack guard to the value we entered _start with.
|
||||
// Then we won't trigger the stack canary check on the way out.
|
||||
__stack_chk_guard = original_stack_chk;
|
||||
|
||||
return 20150614;
|
||||
}
|
||||
}
|
66
Userland/Libraries/LibC/crt0_shared.cpp
Normal file
66
Userland/Libraries/LibC/crt0_shared.cpp
Normal file
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Copyright (c) 2020, the SerenityOS developers.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <AK/Types.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/internals.h>
|
||||
#include <unistd.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
extern u32 __stack_chk_guard;
|
||||
|
||||
int main(int, char**, char**);
|
||||
|
||||
extern void __libc_init();
|
||||
extern void _init();
|
||||
extern char** environ;
|
||||
extern bool __environ_is_malloced;
|
||||
|
||||
int _start(int argc, char** argv, char** env);
|
||||
int _start(int argc, char** argv, char** env)
|
||||
{
|
||||
u32 original_stack_chk = __stack_chk_guard;
|
||||
arc4random_buf(&__stack_chk_guard, sizeof(__stack_chk_guard));
|
||||
|
||||
if (__stack_chk_guard == 0)
|
||||
__stack_chk_guard = original_stack_chk;
|
||||
|
||||
_init();
|
||||
|
||||
int status = main(argc, argv, env);
|
||||
|
||||
// Restore the stack guard to the value we entered _start with,
|
||||
// so we don't trigger the stack canary check on the way out.
|
||||
__stack_chk_guard = original_stack_chk;
|
||||
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
void* __dso_handle __attribute__((__weak__));
|
35
Userland/Libraries/LibC/crti.S
Normal file
35
Userland/Libraries/LibC/crti.S
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
.global _init
|
||||
.section .init
|
||||
_init:
|
||||
push %ebp
|
||||
|
||||
.global _fini
|
||||
.section .fini
|
||||
_fini:
|
||||
push %ebp
|
33
Userland/Libraries/LibC/crtn.S
Normal file
33
Userland/Libraries/LibC/crtn.S
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
.section .init
|
||||
pop %ebp
|
||||
ret
|
||||
|
||||
.section .fini
|
||||
pop %ebp
|
||||
ret
|
63
Userland/Libraries/LibC/ctype.cpp
Normal file
63
Userland/Libraries/LibC/ctype.cpp
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
const char _ctype_[256] = {
|
||||
_C, _C, _C, _C, _C, _C, _C, _C,
|
||||
_C, _C | _S, _C | _S, _C | _S, _C | _S, _C | _S, _C, _C,
|
||||
_C, _C, _C, _C, _C, _C, _C, _C,
|
||||
_C, _C, _C, _C, _C, _C, _C, _C,
|
||||
(char)(_S | _B), _P, _P, _P, _P, _P, _P, _P,
|
||||
_P, _P, _P, _P, _P, _P, _P, _P,
|
||||
_N, _N, _N, _N, _N, _N, _N, _N,
|
||||
_N, _N, _P, _P, _P, _P, _P, _P,
|
||||
_P, _U | _X, _U | _X, _U | _X, _U | _X, _U | _X, _U | _X, _U,
|
||||
_U, _U, _U, _U, _U, _U, _U, _U,
|
||||
_U, _U, _U, _U, _U, _U, _U, _U,
|
||||
_U, _U, _U, _P, _P, _P, _P, _P,
|
||||
_P, _L | _X, _L | _X, _L | _X, _L | _X, _L | _X, _L | _X, _L,
|
||||
_L, _L, _L, _L, _L, _L, _L, _L,
|
||||
_L, _L, _L, _L, _L, _L, _L, _L,
|
||||
_L, _L, _L, _P, _P, _P, _P, _C
|
||||
};
|
||||
|
||||
int tolower(int c)
|
||||
{
|
||||
if (c >= 'A' && c <= 'Z')
|
||||
return c | 0x20;
|
||||
return c;
|
||||
}
|
||||
|
||||
int toupper(int c)
|
||||
{
|
||||
if (c >= 'a' && c <= 'z')
|
||||
return c & ~0x20;
|
||||
return c;
|
||||
}
|
||||
}
|
106
Userland/Libraries/LibC/ctype.h
Normal file
106
Userland/Libraries/LibC/ctype.h
Normal file
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/* Do what newlib does to appease GCC's --with-newlib option. */
|
||||
#define _U 01
|
||||
#define _L 02
|
||||
#define _N 04
|
||||
#define _S 010
|
||||
#define _P 020
|
||||
#define _C 040
|
||||
#define _X 0100
|
||||
#define _B 0200
|
||||
|
||||
extern const char _ctype_[256];
|
||||
|
||||
int tolower(int);
|
||||
int toupper(int);
|
||||
|
||||
static inline int isalnum(int c)
|
||||
{
|
||||
return (_ctype_[(unsigned char)(c)] & (_U | _L | _N));
|
||||
}
|
||||
|
||||
static inline int isalpha(int c)
|
||||
{
|
||||
return (_ctype_[(unsigned char)(c)] & (_U | _L));
|
||||
}
|
||||
|
||||
static inline int iscntrl(int c)
|
||||
{
|
||||
return (_ctype_[(unsigned char)(c)] & (_C));
|
||||
}
|
||||
|
||||
static inline int isdigit(int c)
|
||||
{
|
||||
return (_ctype_[(unsigned char)(c)] & (_N));
|
||||
}
|
||||
|
||||
static inline int isxdigit(int c)
|
||||
{
|
||||
return (_ctype_[(unsigned char)(c)] & (_N | _X));
|
||||
}
|
||||
|
||||
static inline int isspace(int c)
|
||||
{
|
||||
return (_ctype_[(unsigned char)(c)] & (_S));
|
||||
}
|
||||
|
||||
static inline int ispunct(int c)
|
||||
{
|
||||
return (_ctype_[(unsigned char)(c)] & (_P));
|
||||
}
|
||||
|
||||
static inline int isprint(int c)
|
||||
{
|
||||
return (_ctype_[(unsigned char)(c)] & (_P | _U | _L | _N | _B));
|
||||
}
|
||||
|
||||
static inline int isgraph(int c)
|
||||
{
|
||||
return (_ctype_[(unsigned char)(c)] & (_P | _U | _L | _N));
|
||||
}
|
||||
|
||||
static inline int islower(int c)
|
||||
{
|
||||
return ((_ctype_[(unsigned char)(c)] & (_U | _L)) == _L);
|
||||
}
|
||||
|
||||
static inline int isupper(int c)
|
||||
{
|
||||
return ((_ctype_[(unsigned char)(c)] & (_U | _L)) == _U);
|
||||
}
|
||||
|
||||
#define isascii(c) ((unsigned)c <= 127)
|
||||
#define toascii(c) ((c)&127)
|
||||
|
||||
__END_DECLS
|
89
Userland/Libraries/LibC/cxxabi.cpp
Normal file
89
Userland/Libraries/LibC/cxxabi.cpp
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2020, Andrew Kaster <andrewdkaster@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/internals.h>
|
||||
|
||||
//#define GLOBAL_DTORS_DEBUG
|
||||
|
||||
extern "C" {
|
||||
|
||||
struct __exit_entry {
|
||||
AtExitFunction method;
|
||||
void* parameter;
|
||||
void* dso_handle;
|
||||
bool has_been_called;
|
||||
};
|
||||
|
||||
static __exit_entry __exit_entries[1024] {};
|
||||
static int __exit_entry_count = 0;
|
||||
|
||||
int __cxa_atexit(AtExitFunction exit_function, void* parameter, void* dso_handle)
|
||||
{
|
||||
if (__exit_entry_count >= 1024)
|
||||
return -1;
|
||||
|
||||
__exit_entries[__exit_entry_count++] = { exit_function, parameter, dso_handle, false };
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __cxa_finalize(void* dso_handle)
|
||||
{
|
||||
// From the itanium abi, https://itanium-cxx-abi.github.io/cxx-abi/abi.html#dso-dtor-runtime-api
|
||||
//
|
||||
// When __cxa_finalize(d) is called, it should walk the termination function list, calling each in turn
|
||||
// if d matches __dso_handle for the termination function entry. If d == NULL, it should call all of them.
|
||||
// Multiple calls to __cxa_finalize shall not result in calling termination function entries multiple times;
|
||||
// the implementation may either remove entries or mark them finished.
|
||||
|
||||
int entry_index = __exit_entry_count;
|
||||
|
||||
#ifdef GLOBAL_DTORS_DEBUG
|
||||
dbgprintf("__cxa_finalize: %d entries in the finalizer list\n", entry_index);
|
||||
#endif
|
||||
|
||||
while (--entry_index >= 0) {
|
||||
auto& exit_entry = __exit_entries[entry_index];
|
||||
bool needs_calling = !exit_entry.has_been_called && (!dso_handle || dso_handle == exit_entry.dso_handle);
|
||||
if (needs_calling) {
|
||||
#ifdef GLOBAL_DTORS_DEBUG
|
||||
dbgprintf("__cxa_finalize: calling entry[%d] %p(%p) dso: %p\n", entry_index, exit_entry.method, exit_entry.parameter, exit_entry.dso_handle);
|
||||
#endif
|
||||
exit_entry.method(exit_entry.parameter);
|
||||
exit_entry.has_been_called = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[[noreturn]] void __cxa_pure_virtual()
|
||||
{
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
} // extern "C"
|
200
Userland/Libraries/LibC/dirent.cpp
Normal file
200
Userland/Libraries/LibC/dirent.cpp
Normal file
|
@ -0,0 +1,200 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <AK/Assertions.h>
|
||||
#include <AK/StdLibExtras.h>
|
||||
#include <Kernel/API/Syscall.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
DIR* opendir(const char* name)
|
||||
{
|
||||
int fd = open(name, O_RDONLY | O_DIRECTORY);
|
||||
if (fd == -1)
|
||||
return nullptr;
|
||||
DIR* dirp = (DIR*)malloc(sizeof(DIR));
|
||||
dirp->fd = fd;
|
||||
dirp->buffer = nullptr;
|
||||
dirp->buffer_size = 0;
|
||||
dirp->nextptr = nullptr;
|
||||
return dirp;
|
||||
}
|
||||
|
||||
int closedir(DIR* dirp)
|
||||
{
|
||||
if (!dirp || dirp->fd == -1)
|
||||
return -EBADF;
|
||||
if (dirp->buffer)
|
||||
free(dirp->buffer);
|
||||
int rc = close(dirp->fd);
|
||||
if (rc == 0)
|
||||
dirp->fd = -1;
|
||||
free(dirp);
|
||||
return rc;
|
||||
}
|
||||
|
||||
struct [[gnu::packed]] sys_dirent {
|
||||
ino_t ino;
|
||||
u8 file_type;
|
||||
size_t namelen;
|
||||
char name[];
|
||||
size_t total_size()
|
||||
{
|
||||
return sizeof(ino_t) + sizeof(u8) + sizeof(size_t) + sizeof(char) * namelen;
|
||||
}
|
||||
};
|
||||
|
||||
static void create_struct_dirent(sys_dirent* sys_ent, struct dirent* str_ent)
|
||||
{
|
||||
str_ent->d_ino = sys_ent->ino;
|
||||
str_ent->d_type = sys_ent->file_type;
|
||||
str_ent->d_off = 0;
|
||||
str_ent->d_reclen = sys_ent->total_size();
|
||||
for (size_t i = 0; i < sys_ent->namelen; ++i)
|
||||
str_ent->d_name[i] = sys_ent->name[i];
|
||||
// FIXME: I think this null termination behavior is not supposed to be here.
|
||||
str_ent->d_name[sys_ent->namelen] = '\0';
|
||||
}
|
||||
|
||||
static int allocate_dirp_buffer(DIR* dirp)
|
||||
{
|
||||
if (dirp->buffer) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct stat st;
|
||||
// preserve errno since this could be a reentrant call
|
||||
int old_errno = errno;
|
||||
int rc = fstat(dirp->fd, &st);
|
||||
if (rc < 0) {
|
||||
int new_errno = errno;
|
||||
errno = old_errno;
|
||||
return new_errno;
|
||||
}
|
||||
size_t size_to_allocate = max(st.st_size, static_cast<off_t>(4096));
|
||||
dirp->buffer = (char*)malloc(size_to_allocate);
|
||||
ssize_t nread = syscall(SC_get_dir_entries, dirp->fd, dirp->buffer, size_to_allocate);
|
||||
if (nread < 0) {
|
||||
// uh-oh, the syscall returned an error
|
||||
free(dirp->buffer);
|
||||
dirp->buffer = nullptr;
|
||||
return -nread;
|
||||
}
|
||||
dirp->buffer_size = nread;
|
||||
dirp->nextptr = dirp->buffer;
|
||||
return 0;
|
||||
}
|
||||
|
||||
dirent* readdir(DIR* dirp)
|
||||
{
|
||||
if (!dirp)
|
||||
return nullptr;
|
||||
if (dirp->fd == -1)
|
||||
return nullptr;
|
||||
|
||||
if (int new_errno = allocate_dirp_buffer(dirp)) {
|
||||
// readdir is allowed to mutate errno
|
||||
errno = new_errno;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (dirp->nextptr >= (dirp->buffer + dirp->buffer_size))
|
||||
return nullptr;
|
||||
|
||||
auto* sys_ent = (sys_dirent*)dirp->nextptr;
|
||||
create_struct_dirent(sys_ent, &dirp->cur_ent);
|
||||
|
||||
dirp->nextptr += sys_ent->total_size();
|
||||
return &dirp->cur_ent;
|
||||
}
|
||||
|
||||
static bool compare_sys_struct_dirent(sys_dirent* sys_ent, struct dirent* str_ent)
|
||||
{
|
||||
size_t namelen = min((size_t)256, sys_ent->namelen);
|
||||
// These fields are guaranteed by create_struct_dirent to be the same
|
||||
return sys_ent->ino == str_ent->d_ino
|
||||
&& sys_ent->file_type == str_ent->d_type
|
||||
&& sys_ent->total_size() == str_ent->d_reclen
|
||||
&& strncmp(sys_ent->name, str_ent->d_name, namelen) == 0;
|
||||
}
|
||||
|
||||
int readdir_r(DIR* dirp, struct dirent* entry, struct dirent** result)
|
||||
{
|
||||
if (!dirp || dirp->fd == -1) {
|
||||
*result = nullptr;
|
||||
return EBADF;
|
||||
}
|
||||
|
||||
if (int new_errno = allocate_dirp_buffer(dirp)) {
|
||||
*result = nullptr;
|
||||
return new_errno;
|
||||
}
|
||||
|
||||
// This doesn't care about dirp state; seek until we find the entry.
|
||||
// Unfortunately, we can't just compare struct dirent to sys_dirent, so
|
||||
// manually compare the fields. This seems a bit risky, but could work.
|
||||
auto* buffer = dirp->buffer;
|
||||
auto* sys_ent = (sys_dirent*)buffer;
|
||||
bool found = false;
|
||||
while (!(found || buffer >= dirp->buffer + dirp->buffer_size)) {
|
||||
found = compare_sys_struct_dirent(sys_ent, entry);
|
||||
|
||||
// Make sure if we found one, it's the one after (end of buffer or not)
|
||||
buffer += sys_ent->total_size();
|
||||
sys_ent = (sys_dirent*)buffer;
|
||||
}
|
||||
|
||||
// If we found one, but hit end of buffer, then EOD
|
||||
if (found && buffer >= dirp->buffer + dirp->buffer_size) {
|
||||
*result = nullptr;
|
||||
return 0;
|
||||
}
|
||||
// If we never found a match for entry in buffer, start from the beginning
|
||||
else if (!found) {
|
||||
buffer = dirp->buffer;
|
||||
sys_ent = (sys_dirent*)buffer;
|
||||
}
|
||||
|
||||
*result = entry;
|
||||
create_struct_dirent(sys_ent, entry);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dirfd(DIR* dirp)
|
||||
{
|
||||
ASSERT(dirp);
|
||||
return dirp->fd;
|
||||
}
|
||||
}
|
77
Userland/Libraries/LibC/dirent.h
Normal file
77
Userland/Libraries/LibC/dirent.h
Normal file
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
enum {
|
||||
DT_UNKNOWN = 0,
|
||||
#define DT_UNKNOWN DT_UNKNOWN
|
||||
DT_FIFO = 1,
|
||||
#define DT_FIFO DT_FIFO
|
||||
DT_CHR = 2,
|
||||
#define DT_CHR DT_CHR
|
||||
DT_DIR = 4,
|
||||
#define DT_DIR DT_DIR
|
||||
DT_BLK = 6,
|
||||
#define DT_BLK DT_BLK
|
||||
DT_REG = 8,
|
||||
#define DT_REG DT_REG
|
||||
DT_LNK = 10,
|
||||
#define DT_LNK DT_LNK
|
||||
DT_SOCK = 12,
|
||||
#define DT_SOCK DT_SOCK
|
||||
DT_WHT = 14
|
||||
#define DT_WHT DT_WHT
|
||||
};
|
||||
|
||||
struct dirent {
|
||||
ino_t d_ino;
|
||||
off_t d_off;
|
||||
unsigned short d_reclen;
|
||||
unsigned char d_type;
|
||||
char d_name[256];
|
||||
};
|
||||
|
||||
struct __DIR {
|
||||
int fd;
|
||||
struct dirent cur_ent;
|
||||
char* buffer;
|
||||
size_t buffer_size;
|
||||
char* nextptr;
|
||||
};
|
||||
typedef struct __DIR DIR;
|
||||
|
||||
DIR* opendir(const char* name);
|
||||
int closedir(DIR*);
|
||||
struct dirent* readdir(DIR*);
|
||||
int readdir_r(DIR*, struct dirent*, struct dirent**);
|
||||
int dirfd(DIR*);
|
||||
|
||||
__END_DECLS
|
131
Userland/Libraries/LibC/dlfcn.cpp
Normal file
131
Userland/Libraries/LibC/dlfcn.cpp
Normal file
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <dlfcn.h>
|
||||
#include <fcntl.h>
|
||||
#include <mman.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <AK/HashMap.h>
|
||||
#include <AK/LexicalPath.h>
|
||||
#include <AK/RefPtr.h>
|
||||
#include <AK/ScopeGuard.h>
|
||||
#include <AK/String.h>
|
||||
#include <AK/StringBuilder.h>
|
||||
#include <LibELF/DynamicLoader.h>
|
||||
|
||||
// NOTE: The string here should never include a trailing newline (according to POSIX)
|
||||
String g_dlerror_msg;
|
||||
|
||||
HashMap<String, RefPtr<ELF::DynamicLoader>> g_elf_objects;
|
||||
|
||||
extern "C" {
|
||||
|
||||
int dlclose(void*)
|
||||
{
|
||||
g_dlerror_msg = "dlclose not implemented!";
|
||||
return -1;
|
||||
}
|
||||
|
||||
char* dlerror()
|
||||
{
|
||||
return const_cast<char*>(g_dlerror_msg.characters());
|
||||
}
|
||||
|
||||
void* dlopen(const char* filename, int flags)
|
||||
{
|
||||
// FIXME: Create a global mutex/semaphore/lock for dlopen/dlclose/dlsym and (?) dlerror
|
||||
// FIXME: refcount?
|
||||
|
||||
if (!filename) {
|
||||
// FIXME: Return the handle for "the main executable"
|
||||
// The Serenity Kernel will keep a mapping of the main elf binary resident in memory,
|
||||
// But a future dynamic loader might have a different idea/way of letting us access this information
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
auto basename = LexicalPath(filename).basename();
|
||||
|
||||
auto existing_elf_object = g_elf_objects.get(basename);
|
||||
if (existing_elf_object.has_value()) {
|
||||
return const_cast<ELF::DynamicLoader*>(existing_elf_object.value());
|
||||
}
|
||||
|
||||
int fd = open(filename, O_RDONLY);
|
||||
if (!fd) {
|
||||
g_dlerror_msg = String::format("Unable to open file %s", filename);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ScopeGuard close_fd_guard([fd]() { close(fd); });
|
||||
|
||||
struct stat file_stats {
|
||||
};
|
||||
|
||||
int ret = fstat(fd, &file_stats);
|
||||
if (ret < 0) {
|
||||
g_dlerror_msg = String::format("Unable to stat file %s", filename);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto loader = ELF::DynamicLoader::construct(filename, fd, file_stats.st_size);
|
||||
|
||||
if (!loader->is_valid()) {
|
||||
g_dlerror_msg = String::format("%s is not a valid ELF dynamic shared object!", filename);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!loader->load_from_image(flags,
|
||||
0 // total_tls_size = 0, FIXME: Support TLS when using dlopen()
|
||||
)) {
|
||||
g_dlerror_msg = String::format("Failed to load ELF object %s", filename);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
g_elf_objects.set(basename, move(loader));
|
||||
g_dlerror_msg = "Successfully loaded ELF object.";
|
||||
|
||||
// we have one refcount already
|
||||
return const_cast<ELF::DynamicLoader*>(g_elf_objects.get(basename).value());
|
||||
}
|
||||
|
||||
void* dlsym(void* handle, const char* symbol_name)
|
||||
{
|
||||
// FIXME: When called with a NULL handle we're supposed to search every dso in the process... that'll get expensive
|
||||
ASSERT(handle);
|
||||
auto* dso = reinterpret_cast<ELF::DynamicLoader*>(handle);
|
||||
void* symbol = dso->symbol_for_name(symbol_name);
|
||||
if (!symbol) {
|
||||
g_dlerror_msg = "Symbol not found";
|
||||
return nullptr;
|
||||
}
|
||||
return symbol;
|
||||
}
|
||||
|
||||
} // extern "C"
|
44
Userland/Libraries/LibC/dlfcn.h
Normal file
44
Userland/Libraries/LibC/dlfcn.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
#define RTLD_DEFAULT 0
|
||||
#define RTLD_LAZY 2
|
||||
#define RTLD_NOW 4
|
||||
#define RTLD_GLOBAL 8
|
||||
#define RTLD_LOCAL 16
|
||||
|
||||
int dlclose(void*);
|
||||
char* dlerror();
|
||||
void* dlopen(const char*, int);
|
||||
void* dlsym(void*, const char*);
|
||||
|
||||
__END_DECLS
|
109
Userland/Libraries/LibC/endian.h
Normal file
109
Userland/Libraries/LibC/endian.h
Normal file
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
#define __LITTLE_ENDIAN 1234
|
||||
#define __BIG_ENDIAN 4321
|
||||
#define __PDP_ENDIAN 3412
|
||||
|
||||
#if defined(__GNUC__) && defined(__BYTE_ORDER__)
|
||||
# define __BYTE_ORDER __BYTE_ORDER__
|
||||
#else
|
||||
# include <bits/endian.h>
|
||||
#endif
|
||||
|
||||
#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
|
||||
|
||||
# include <stdint.h>
|
||||
|
||||
static __inline uint16_t __bswap16(uint16_t x)
|
||||
{
|
||||
return __builtin_bswap16(x);
|
||||
}
|
||||
|
||||
static __inline uint32_t __bswap32(uint32_t x)
|
||||
{
|
||||
return __builtin_bswap32(x);
|
||||
}
|
||||
|
||||
static __inline uint64_t __bswap64(uint64_t x)
|
||||
{
|
||||
return __builtin_bswap64(x);
|
||||
}
|
||||
|
||||
# define LITTLE_ENDIAN __LITTLE_ENDIAN
|
||||
# define BIG_ENDIAN __BIG_ENDIAN
|
||||
# define PDP_ENDIAN __PDP_ENDIAN
|
||||
# define BYTE_ORDER __BYTE_ORDER
|
||||
|
||||
# if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
# define htole16(x) ((uint16_t)(x))
|
||||
# define le16toh(x) ((uint16_t)(x))
|
||||
# define letoh16(x) ((uint16_t)(x))
|
||||
# define htole32(x) ((uint32_t)(x))
|
||||
# define le32toh(x) ((uint32_t)(x))
|
||||
# define letoh32(x) ((uint32_t)(x))
|
||||
# define htole64(x) ((uint64_t)(x))
|
||||
# define le64toh(x) ((uint64_t)(x))
|
||||
# define letoh64(x) ((uint64_t)(x))
|
||||
# define htobe16(x) (__builtin_bswap16(x))
|
||||
# define be16toh(x) (__builtin_bswap16(x))
|
||||
# define betoh16(x) (__builtin_bswap16(x))
|
||||
# define htobe32(x) (__builtin_bswap32(x))
|
||||
# define be32toh(x) (__builtin_bswap32(x))
|
||||
# define betoh32(x) (__builtin_bswap32(x))
|
||||
# define htobe64(x) (__builtin_bswap64(x))
|
||||
# define be64toh(x) (__builtin_bswap64(x))
|
||||
# define betoh64(x) (__builtin_bswap64(x))
|
||||
# else
|
||||
# define htole16(x) (__builtin_bswap16(x))
|
||||
# define le16toh(x) (__builtin_bswap16(x))
|
||||
# define letoh16(x) (__builtin_bswap16(x))
|
||||
# define htole32(x) (__builtin_bswap32(x))
|
||||
# define le32toh(x) (__builtin_bswap32(x))
|
||||
# define letoh32(x) (__builtin_bswap32(x))
|
||||
# define htole64(x) (__builtin_bswap64(x))
|
||||
# define le64toh(x) (__builtin_bswap64(x))
|
||||
# define letoh64(x) (__builtin_bswap64(x))
|
||||
# define htobe16(x) ((uint16_t)(x))
|
||||
# define be16toh(x) ((uint16_t)(x))
|
||||
# define betoh16(x) ((uint16_t)(x))
|
||||
# define htobe32(x) ((uint32_t)(x))
|
||||
# define be32toh(x) ((uint32_t)(x))
|
||||
# define betoh32(x) ((uint32_t)(x))
|
||||
# define htobe64(x) ((uint64_t)(x))
|
||||
# define be64toh(x) ((uint64_t)(x))
|
||||
# define betoh64(x) ((uint64_t)(x))
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
__END_DECLS
|
55
Userland/Libraries/LibC/errno.h
Normal file
55
Userland/Libraries/LibC/errno.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <errno_numbers.h>
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#define __RETURN_WITH_ERRNO(rc, good_ret, bad_ret) \
|
||||
do { \
|
||||
if (rc < 0) { \
|
||||
errno = -rc; \
|
||||
return (bad_ret); \
|
||||
} \
|
||||
errno = 0; \
|
||||
return (good_ret); \
|
||||
} while (0)
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
extern const char* const sys_errlist[];
|
||||
extern int sys_nerr;
|
||||
|
||||
#ifdef NO_TLS
|
||||
extern int errno;
|
||||
#else
|
||||
extern __thread int errno;
|
||||
#endif
|
||||
|
||||
#define errno errno
|
||||
|
||||
__END_DECLS
|
103
Userland/Libraries/LibC/errno_numbers.h
Normal file
103
Userland/Libraries/LibC/errno_numbers.h
Normal file
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define EPERM 1
|
||||
#define ENOENT 2
|
||||
#define ESRCH 3
|
||||
#define EINTR 4
|
||||
#define EIO 5
|
||||
#define ENXIO 6
|
||||
#define E2BIG 7
|
||||
#define ENOEXEC 8
|
||||
#define EBADF 9
|
||||
#define ECHILD 10
|
||||
#define EAGAIN 11
|
||||
#define ENOMEM 12
|
||||
#define EACCES 13
|
||||
#define EFAULT 14
|
||||
#define ENOTBLK 15
|
||||
#define EBUSY 16
|
||||
#define EEXIST 17
|
||||
#define EXDEV 18
|
||||
#define ENODEV 19
|
||||
#define ENOTDIR 20
|
||||
#define EISDIR 21
|
||||
#define EINVAL 22
|
||||
#define ENFILE 23
|
||||
#define EMFILE 24
|
||||
#define ENOTTY 25
|
||||
#define ETXTBSY 26
|
||||
#define EFBIG 27
|
||||
#define ENOSPC 28
|
||||
#define ESPIPE 29
|
||||
#define EROFS 30
|
||||
#define EMLINK 31
|
||||
#define EPIPE 32
|
||||
#define ERANGE 33
|
||||
#define ENAMETOOLONG 34
|
||||
#define ELOOP 35
|
||||
#define EOVERFLOW 36
|
||||
#define EOPNOTSUPP 37
|
||||
#define ENOSYS 38
|
||||
#define ENOTIMPL 39
|
||||
#define EAFNOSUPPORT 40
|
||||
#define ENOTSOCK 41
|
||||
#define EADDRINUSE 42
|
||||
#define EWHYTHO 43
|
||||
#define ENOTEMPTY 44
|
||||
#define EDOM 45
|
||||
#define ECONNREFUSED 46
|
||||
#define EADDRNOTAVAIL 47
|
||||
#define EISCONN 48
|
||||
#define ECONNABORTED 49
|
||||
#define EALREADY 50
|
||||
#define ECONNRESET 51
|
||||
#define EDESTADDRREQ 52
|
||||
#define EHOSTUNREACH 53
|
||||
#define EILSEQ 54
|
||||
#define EMSGSIZE 55
|
||||
#define ENETDOWN 56
|
||||
#define ENETUNREACH 57
|
||||
#define ENETRESET 58
|
||||
#define ENOBUFS 59
|
||||
#define ENOLCK 60
|
||||
#define ENOMSG 61
|
||||
#define ENOPROTOOPT 62
|
||||
#define ENOTCONN 63
|
||||
#define EWOULDBLOCK 64
|
||||
#define EPROTONOSUPPORT 65
|
||||
#define EDEADLK 66
|
||||
#define ETIMEDOUT 67
|
||||
#define EPROTOTYPE 68
|
||||
#define EINPROGRESS 69
|
||||
#define ENOTHREAD 70
|
||||
#define EPROTO 71
|
||||
#define ENOTSUP 72
|
||||
#define EPFNOSUPPORT 73
|
||||
#define EDIRINTOSELF 74
|
||||
#define EMAXERRNO 75
|
106
Userland/Libraries/LibC/fcntl.cpp
Normal file
106
Userland/Libraries/LibC/fcntl.cpp
Normal file
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <Kernel/API/Syscall.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
int fcntl(int fd, int cmd, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, cmd);
|
||||
u32 extra_arg = va_arg(ap, u32);
|
||||
int rc = syscall(SC_fcntl, fd, cmd, extra_arg);
|
||||
va_end(ap);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
|
||||
int watch_file(const char* path, size_t path_length)
|
||||
{
|
||||
int rc = syscall(SC_watch_file, path, path_length);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
|
||||
int creat(const char* path, mode_t mode)
|
||||
{
|
||||
return open(path, O_CREAT | O_WRONLY | O_TRUNC, mode);
|
||||
}
|
||||
|
||||
int creat_with_path_length(const char* path, size_t path_length, mode_t mode)
|
||||
{
|
||||
return open_with_path_length(path, path_length, O_CREAT | O_WRONLY | O_TRUNC, mode);
|
||||
}
|
||||
|
||||
int open_with_path_length(const char* path, size_t path_length, int options, mode_t mode)
|
||||
{
|
||||
return openat_with_path_length(AT_FDCWD, path, path_length, options, mode);
|
||||
}
|
||||
|
||||
int openat_with_path_length(int dirfd, const char* path, size_t path_length, int options, mode_t mode)
|
||||
{
|
||||
if (!path) {
|
||||
errno = EFAULT;
|
||||
return -1;
|
||||
}
|
||||
if (path_length > INT32_MAX) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
Syscall::SC_open_params params { dirfd, { path, path_length }, options, mode };
|
||||
int rc = syscall(SC_open, ¶ms);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
|
||||
int open(const char* path, int options, ...)
|
||||
{
|
||||
if (!path) {
|
||||
errno = EFAULT;
|
||||
return -1;
|
||||
}
|
||||
va_list ap;
|
||||
va_start(ap, options);
|
||||
auto mode = (mode_t)va_arg(ap, unsigned);
|
||||
va_end(ap);
|
||||
return open_with_path_length(path, strlen(path), options, mode);
|
||||
}
|
||||
|
||||
int openat(int dirfd, const char* path, int options, ...)
|
||||
{
|
||||
if (!path) {
|
||||
errno = EFAULT;
|
||||
return -1;
|
||||
}
|
||||
va_list ap;
|
||||
va_start(ap, options);
|
||||
auto mode = (mode_t)va_arg(ap, unsigned);
|
||||
va_end(ap);
|
||||
return openat_with_path_length(dirfd, path, strlen(path), options, mode);
|
||||
}
|
||||
}
|
111
Userland/Libraries/LibC/fcntl.h
Normal file
111
Userland/Libraries/LibC/fcntl.h
Normal file
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
#define F_DUPFD 0
|
||||
#define F_GETFD 1
|
||||
#define F_SETFD 2
|
||||
#define F_GETFL 3
|
||||
#define F_SETFL 4
|
||||
#define F_ISTTY 5
|
||||
|
||||
#define FD_CLOEXEC 1
|
||||
|
||||
#define O_RDONLY (1 << 0)
|
||||
#define O_WRONLY (1 << 1)
|
||||
#define O_RDWR (O_RDONLY | O_WRONLY)
|
||||
#define O_ACCMODE (O_RDONLY | O_WRONLY)
|
||||
#define O_EXEC (1 << 2)
|
||||
#define O_CREAT (1 << 3)
|
||||
#define O_EXCL (1 << 4)
|
||||
#define O_NOCTTY (1 << 5)
|
||||
#define O_TRUNC (1 << 6)
|
||||
#define O_APPEND (1 << 7)
|
||||
#define O_NONBLOCK (1 << 8)
|
||||
#define O_DIRECTORY (1 << 9)
|
||||
#define O_NOFOLLOW (1 << 10)
|
||||
#define O_CLOEXEC (1 << 11)
|
||||
#define O_DIRECT (1 << 12)
|
||||
|
||||
#define S_IFMT 0170000
|
||||
#define S_IFDIR 0040000
|
||||
#define S_IFCHR 0020000
|
||||
#define S_IFBLK 0060000
|
||||
#define S_IFREG 0100000
|
||||
#define S_IFIFO 0010000
|
||||
#define S_IFLNK 0120000
|
||||
#define S_IFSOCK 0140000
|
||||
|
||||
#define S_ISUID 04000
|
||||
#define S_ISGID 02000
|
||||
#define S_ISVTX 01000
|
||||
#define S_IRUSR 0400
|
||||
#define S_IWUSR 0200
|
||||
#define S_IXUSR 0100
|
||||
#define S_IRGRP 0040
|
||||
#define S_IWGRP 0020
|
||||
#define S_IXGRP 0010
|
||||
#define S_IROTH 0004
|
||||
#define S_IWOTH 0002
|
||||
#define S_IXOTH 0001
|
||||
|
||||
#define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR)
|
||||
|
||||
#define S_IRWXG (S_IRWXU >> 3)
|
||||
#define S_IRWXO (S_IRWXG >> 3)
|
||||
|
||||
int creat(const char* path, mode_t);
|
||||
int open(const char* path, int options, ...);
|
||||
int creat_with_path_length(const char* path, size_t path_length, mode_t);
|
||||
int open_with_path_length(const char* path, size_t path_length, int options, mode_t);
|
||||
#define AT_FDCWD -100
|
||||
int openat(int dirfd, const char* path, int options, ...);
|
||||
int openat_with_path_length(int dirfd, const char* path, size_t path_length, int options, mode_t);
|
||||
|
||||
int fcntl(int fd, int cmd, ...);
|
||||
int watch_file(const char* path, size_t path_length);
|
||||
|
||||
#define F_RDLCK 0
|
||||
#define F_WRLCK 1
|
||||
#define F_UNLCK 2
|
||||
#define F_SETLK 6
|
||||
#define F_SETLKW 7
|
||||
|
||||
struct flock {
|
||||
short l_type;
|
||||
short l_whence;
|
||||
off_t l_start;
|
||||
off_t l_len;
|
||||
pid_t l_pid;
|
||||
};
|
||||
|
||||
__END_DECLS
|
39
Userland/Libraries/LibC/fd_set.h
Normal file
39
Userland/Libraries/LibC/fd_set.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define FD_SETSIZE 64
|
||||
#define FD_ZERO(set) memset((set), 0, sizeof(fd_set));
|
||||
#define FD_CLR(fd, set) ((set)->bits[(fd / 8)] &= ~(1 << (fd) % 8))
|
||||
#define FD_SET(fd, set) ((set)->bits[(fd / 8)] |= (1 << (fd) % 8))
|
||||
#define FD_ISSET(fd, set) ((set)->bits[(fd / 8)] & (1 << (fd) % 8))
|
||||
|
||||
struct __fd_set {
|
||||
unsigned char bits[FD_SETSIZE / 8];
|
||||
};
|
||||
|
||||
typedef struct __fd_set fd_set;
|
27
Userland/Libraries/LibC/float.h
Normal file
27
Userland/Libraries/LibC/float.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
369
Userland/Libraries/LibC/getopt.cpp
Normal file
369
Userland/Libraries/LibC/getopt.cpp
Normal file
|
@ -0,0 +1,369 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Sergey Bugaev <bugaevc@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <AK/StringView.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int opterr = 1;
|
||||
int optopt = 0;
|
||||
int optind = 1;
|
||||
int optreset = 0;
|
||||
char* optarg = nullptr;
|
||||
|
||||
// POSIX says, "When an element of argv[] contains multiple option characters,
|
||||
// it is unspecified how getopt() determines which options have already been
|
||||
// processed". Well, this is how we do it.
|
||||
static size_t s_index_into_multioption_argument = 0;
|
||||
|
||||
static inline void report_error(const char* format, ...)
|
||||
{
|
||||
if (!opterr)
|
||||
return;
|
||||
|
||||
fputs("\033[31m", stderr);
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
vfprintf(stderr, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
fputs("\033[0m\n", stderr);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
class OptionParser {
|
||||
public:
|
||||
OptionParser(int argc, char** argv, const StringView& short_options, const option* long_options, int* out_long_option_index = nullptr);
|
||||
int getopt();
|
||||
|
||||
private:
|
||||
bool lookup_short_option(char option, int& needs_value) const;
|
||||
int handle_short_option();
|
||||
|
||||
const option* lookup_long_option(char* raw) const;
|
||||
int handle_long_option();
|
||||
|
||||
void shift_argv();
|
||||
bool find_next_option();
|
||||
|
||||
size_t m_argc { 0 };
|
||||
char** m_argv { nullptr };
|
||||
StringView m_short_options;
|
||||
const option* m_long_options { nullptr };
|
||||
int* m_out_long_option_index { nullptr };
|
||||
bool m_stop_on_first_non_option { false };
|
||||
|
||||
size_t m_arg_index { 0 };
|
||||
size_t m_consumed_args { 0 };
|
||||
};
|
||||
|
||||
OptionParser::OptionParser(int argc, char** argv, const StringView& short_options, const option* long_options, int* out_long_option_index)
|
||||
: m_argc(argc)
|
||||
, m_argv(argv)
|
||||
, m_short_options(short_options)
|
||||
, m_long_options(long_options)
|
||||
, m_out_long_option_index(out_long_option_index)
|
||||
{
|
||||
// In the following case:
|
||||
// $ foo bar -o baz
|
||||
// we want to parse the option (-o baz) first, and leave the argument (bar)
|
||||
// in argv after we return -1 when invoked the second time. So we reorder
|
||||
// argv to put options first and positional arguments next. To turn this
|
||||
// behavior off, start the short options spec with a "+". This is a GNU
|
||||
// extension that we support.
|
||||
m_stop_on_first_non_option = short_options.starts_with('+');
|
||||
|
||||
// See if we should reset the internal state.
|
||||
if (optreset || optind == 0) {
|
||||
optreset = 0;
|
||||
optind = 1;
|
||||
s_index_into_multioption_argument = 0;
|
||||
}
|
||||
|
||||
optopt = 0;
|
||||
optarg = nullptr;
|
||||
}
|
||||
|
||||
int OptionParser::getopt()
|
||||
{
|
||||
bool should_reorder_argv = !m_stop_on_first_non_option;
|
||||
int res = -1;
|
||||
|
||||
bool found_an_option = find_next_option();
|
||||
StringView arg = m_argv[m_arg_index];
|
||||
|
||||
if (!found_an_option) {
|
||||
res = -1;
|
||||
if (arg == "--")
|
||||
m_consumed_args = 1;
|
||||
else
|
||||
m_consumed_args = 0;
|
||||
} else {
|
||||
// Alright, so we have an option on our hands!
|
||||
bool is_long_option = arg.starts_with("--");
|
||||
if (is_long_option)
|
||||
res = handle_long_option();
|
||||
else
|
||||
res = handle_short_option();
|
||||
|
||||
// If we encountered an error, return immediately.
|
||||
if (res == '?')
|
||||
return '?';
|
||||
}
|
||||
|
||||
if (should_reorder_argv)
|
||||
shift_argv();
|
||||
else
|
||||
ASSERT(optind == static_cast<int>(m_arg_index));
|
||||
optind += m_consumed_args;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
bool OptionParser::lookup_short_option(char option, int& needs_value) const
|
||||
{
|
||||
Vector<StringView> parts = m_short_options.split_view(option, true);
|
||||
|
||||
ASSERT(parts.size() <= 2);
|
||||
if (parts.size() < 2) {
|
||||
// Haven't found the option in the spec.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (parts[1].starts_with("::")) {
|
||||
// If an option is followed by two colons, it optionally accepts an
|
||||
// argument.
|
||||
needs_value = optional_argument;
|
||||
} else if (parts[1].starts_with(':')) {
|
||||
// If it's followed by one colon, it requires an argument.
|
||||
needs_value = required_argument;
|
||||
} else {
|
||||
// Otherwise, it doesn't accept arguments.
|
||||
needs_value = no_argument;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int OptionParser::handle_short_option()
|
||||
{
|
||||
StringView arg = m_argv[m_arg_index];
|
||||
ASSERT(arg.starts_with('-'));
|
||||
|
||||
if (s_index_into_multioption_argument == 0) {
|
||||
// Just starting to parse this argument, skip the "-".
|
||||
s_index_into_multioption_argument = 1;
|
||||
}
|
||||
char option = arg[s_index_into_multioption_argument];
|
||||
s_index_into_multioption_argument++;
|
||||
|
||||
int needs_value = no_argument;
|
||||
bool ok = lookup_short_option(option, needs_value);
|
||||
if (!ok) {
|
||||
optopt = option;
|
||||
report_error("Unrecognized option \033[1m-%c\033[22m", option);
|
||||
return '?';
|
||||
}
|
||||
|
||||
// Let's see if we're at the end of this argument already.
|
||||
if (s_index_into_multioption_argument < arg.length()) {
|
||||
// This not yet the end.
|
||||
if (needs_value == no_argument) {
|
||||
optarg = nullptr;
|
||||
m_consumed_args = 0;
|
||||
} else {
|
||||
// Treat the rest of the argument as the value, the "-ovalue"
|
||||
// syntax.
|
||||
optarg = m_argv[m_arg_index] + s_index_into_multioption_argument;
|
||||
// Next time, process the next argument.
|
||||
s_index_into_multioption_argument = 0;
|
||||
m_consumed_args = 1;
|
||||
}
|
||||
} else {
|
||||
s_index_into_multioption_argument = 0;
|
||||
if (needs_value != required_argument) {
|
||||
optarg = nullptr;
|
||||
m_consumed_args = 1;
|
||||
} else if (m_arg_index + 1 < m_argc) {
|
||||
// Treat the next argument as a value, the "-o value" syntax.
|
||||
optarg = m_argv[m_arg_index + 1];
|
||||
m_consumed_args = 2;
|
||||
} else {
|
||||
report_error("Missing value for option \033[1m-%c\033[22m", option);
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
|
||||
return option;
|
||||
}
|
||||
|
||||
const option* OptionParser::lookup_long_option(char* raw) const
|
||||
{
|
||||
StringView arg = raw;
|
||||
|
||||
for (size_t index = 0; m_long_options[index].name; index++) {
|
||||
auto& option = m_long_options[index];
|
||||
StringView name = option.name;
|
||||
|
||||
if (!arg.starts_with(name))
|
||||
continue;
|
||||
|
||||
// It would be better to not write out the index at all unless we're
|
||||
// sure we've found the right option, but whatever.
|
||||
if (m_out_long_option_index)
|
||||
*m_out_long_option_index = index;
|
||||
|
||||
// Can either be "--option" or "--option=value".
|
||||
if (arg.length() == name.length()) {
|
||||
optarg = nullptr;
|
||||
return &option;
|
||||
}
|
||||
ASSERT(arg.length() > name.length());
|
||||
if (arg[name.length()] == '=') {
|
||||
optarg = raw + name.length() + 1;
|
||||
return &option;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int OptionParser::handle_long_option()
|
||||
{
|
||||
ASSERT(StringView(m_argv[m_arg_index]).starts_with("--"));
|
||||
|
||||
// We cannot set optopt to anything sensible for long options, so set it to 0.
|
||||
optopt = 0;
|
||||
|
||||
auto* option = lookup_long_option(m_argv[m_arg_index] + 2);
|
||||
if (!option) {
|
||||
report_error("Unrecognized option \033[1m%s\033[22m", m_argv[m_arg_index]);
|
||||
return '?';
|
||||
}
|
||||
// lookup_long_option() will also set optarg if the value of the option is
|
||||
// specified using "--option=value" syntax.
|
||||
|
||||
// Figure out whether this option needs and/or has a value (also called "an
|
||||
// argument", but let's not call it that to distinguish it from argv
|
||||
// elements).
|
||||
switch (option->has_arg) {
|
||||
case no_argument:
|
||||
if (optarg) {
|
||||
report_error("Option \033[1m--%s\033[22m doesn't accept an argument", option->name);
|
||||
return '?';
|
||||
}
|
||||
m_consumed_args = 1;
|
||||
break;
|
||||
case optional_argument:
|
||||
m_consumed_args = 1;
|
||||
break;
|
||||
case required_argument:
|
||||
if (optarg) {
|
||||
// Value specified using "--option=value" syntax.
|
||||
m_consumed_args = 1;
|
||||
} else if (m_arg_index + 1 < m_argc) {
|
||||
// Treat the next argument as a value in "--option value" syntax.
|
||||
optarg = m_argv[m_arg_index + 1];
|
||||
m_consumed_args = 2;
|
||||
} else {
|
||||
report_error("Missing value for option \033[1m--%s\033[22m", option->name);
|
||||
return '?';
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
// Now that we've figured the value out, see about reporting this option to
|
||||
// our caller.
|
||||
if (option->flag) {
|
||||
*option->flag = option->val;
|
||||
return 0;
|
||||
}
|
||||
return option->val;
|
||||
}
|
||||
|
||||
void OptionParser::shift_argv()
|
||||
{
|
||||
// We've just parsed an option (which perhaps has a value).
|
||||
// Put the option (along with it value, if any) in front of other arguments.
|
||||
ASSERT(optind <= static_cast<int>(m_arg_index));
|
||||
|
||||
if (optind == static_cast<int>(m_arg_index) || m_consumed_args == 0) {
|
||||
// Nothing to do!
|
||||
return;
|
||||
}
|
||||
|
||||
char* buffer[m_consumed_args];
|
||||
memcpy(buffer, &m_argv[m_arg_index], sizeof(char*) * m_consumed_args);
|
||||
memmove(&m_argv[optind + m_consumed_args], &m_argv[optind], sizeof(char*) * (m_arg_index - optind));
|
||||
memcpy(&m_argv[optind], buffer, sizeof(char*) * m_consumed_args);
|
||||
}
|
||||
|
||||
bool OptionParser::find_next_option()
|
||||
{
|
||||
for (m_arg_index = optind; m_arg_index < m_argc && m_argv[m_arg_index]; m_arg_index++) {
|
||||
StringView arg = m_argv[m_arg_index];
|
||||
// Anything that doesn't start with a "-" is not an option.
|
||||
if (!arg.starts_with('-')) {
|
||||
if (m_stop_on_first_non_option)
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
// As a special case, a single "-" is not an option either.
|
||||
// (It's typically used by programs to refer to stdin).
|
||||
if (arg == "-")
|
||||
continue;
|
||||
// As another special case, a "--" is not an option either, and we stop
|
||||
// looking for further options if we encounter it.
|
||||
if (arg == "--")
|
||||
return false;
|
||||
// Otherwise, we have found an option!
|
||||
return true;
|
||||
}
|
||||
|
||||
// Reached the end and still found no options.
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int getopt(int argc, char** argv, const char* short_options)
|
||||
{
|
||||
option dummy { nullptr, 0, nullptr, 0 };
|
||||
OptionParser parser { argc, argv, short_options, &dummy };
|
||||
return parser.getopt();
|
||||
}
|
||||
|
||||
int getopt_long(int argc, char** argv, const char* short_options, const struct option* long_options, int* out_long_option_index)
|
||||
{
|
||||
OptionParser parser { argc, argv, short_options, long_options, out_long_option_index };
|
||||
return parser.getopt();
|
||||
}
|
46
Userland/Libraries/LibC/getopt.h
Normal file
46
Userland/Libraries/LibC/getopt.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Sergey Bugaev <bugaevc@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
#define no_argument 0
|
||||
#define required_argument 1
|
||||
#define optional_argument 2
|
||||
|
||||
struct option {
|
||||
const char* name;
|
||||
int has_arg;
|
||||
int* flag;
|
||||
int val;
|
||||
};
|
||||
|
||||
int getopt_long(int argc, char** argv, const char* short_options, const struct option* long_options, int* out_long_option_index);
|
||||
|
||||
__END_DECLS
|
182
Userland/Libraries/LibC/grp.cpp
Normal file
182
Userland/Libraries/LibC/grp.cpp
Normal file
|
@ -0,0 +1,182 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <AK/String.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <errno_numbers.h>
|
||||
#include <grp.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
static FILE* s_stream = nullptr;
|
||||
static unsigned s_line_number = 0;
|
||||
static struct group s_group;
|
||||
|
||||
static String s_name;
|
||||
static String s_passwd;
|
||||
static Vector<String> s_members;
|
||||
static Vector<const char*> s_members_ptrs;
|
||||
|
||||
void setgrent()
|
||||
{
|
||||
s_line_number = 0;
|
||||
if (s_stream) {
|
||||
rewind(s_stream);
|
||||
} else {
|
||||
s_stream = fopen("/etc/group", "r");
|
||||
if (!s_stream) {
|
||||
perror("open /etc/group");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void endgrent()
|
||||
{
|
||||
s_line_number = 0;
|
||||
if (s_stream) {
|
||||
fclose(s_stream);
|
||||
s_stream = nullptr;
|
||||
}
|
||||
|
||||
memset(&s_group, 0, sizeof(s_group));
|
||||
|
||||
s_name = {};
|
||||
s_passwd = {};
|
||||
s_members = {};
|
||||
s_members_ptrs = {};
|
||||
}
|
||||
|
||||
struct group* getgrgid(gid_t gid)
|
||||
{
|
||||
setgrent();
|
||||
while (auto* gr = getgrent()) {
|
||||
if (gr->gr_gid == gid)
|
||||
return gr;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
struct group* getgrnam(const char* name)
|
||||
{
|
||||
setgrent();
|
||||
while (auto* gr = getgrent()) {
|
||||
if (!strcmp(gr->gr_name, name))
|
||||
return gr;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static bool parse_grpdb_entry(const String& line)
|
||||
{
|
||||
auto parts = line.split_view(':', true);
|
||||
if (parts.size() != 4) {
|
||||
fprintf(stderr, "getgrent(): Malformed entry on line %u: '%s' has %zu parts\n", s_line_number, line.characters(), parts.size());
|
||||
return false;
|
||||
}
|
||||
|
||||
s_name = parts[0];
|
||||
s_passwd = parts[1];
|
||||
|
||||
auto& gid_string = parts[2];
|
||||
String members_string = parts[3];
|
||||
|
||||
auto gid = gid_string.to_uint();
|
||||
if (!gid.has_value()) {
|
||||
fprintf(stderr, "getgrent(): Malformed GID on line %u\n", s_line_number);
|
||||
return false;
|
||||
}
|
||||
|
||||
s_members = members_string.split(',');
|
||||
s_members_ptrs.clear_with_capacity();
|
||||
s_members_ptrs.ensure_capacity(s_members.size() + 1);
|
||||
for (auto& member : s_members) {
|
||||
s_members_ptrs.append(member.characters());
|
||||
}
|
||||
s_members_ptrs.append(nullptr);
|
||||
|
||||
s_group.gr_gid = gid.value();
|
||||
s_group.gr_name = const_cast<char*>(s_name.characters());
|
||||
s_group.gr_passwd = const_cast<char*>(s_passwd.characters());
|
||||
s_group.gr_mem = const_cast<char**>(s_members_ptrs.data());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
struct group* getgrent()
|
||||
{
|
||||
if (!s_stream)
|
||||
setgrent();
|
||||
|
||||
while (true) {
|
||||
if (!s_stream || feof(s_stream))
|
||||
return nullptr;
|
||||
|
||||
if (ferror(s_stream)) {
|
||||
fprintf(stderr, "getgrent(): Read error: %s\n", strerror(ferror(s_stream)));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
char buffer[1024];
|
||||
++s_line_number;
|
||||
char* s = fgets(buffer, sizeof(buffer), s_stream);
|
||||
|
||||
// Silently tolerate an empty line at the end.
|
||||
if ((!s || !s[0]) && feof(s_stream))
|
||||
return nullptr;
|
||||
|
||||
String line(s, Chomp);
|
||||
if (parse_grpdb_entry(line))
|
||||
return &s_group;
|
||||
// Otherwise, proceed to the next line.
|
||||
}
|
||||
}
|
||||
|
||||
int initgroups(const char* user, gid_t extra_gid)
|
||||
{
|
||||
size_t count = 0;
|
||||
gid_t gids[32];
|
||||
bool extra_gid_added = false;
|
||||
setgrent();
|
||||
while (auto* gr = getgrent()) {
|
||||
for (auto* mem = gr->gr_mem; *mem; ++mem) {
|
||||
if (!strcmp(*mem, user)) {
|
||||
gids[count++] = gr->gr_gid;
|
||||
if (gr->gr_gid == extra_gid)
|
||||
extra_gid_added = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
endgrent();
|
||||
if (!extra_gid_added)
|
||||
gids[count++] = extra_gid;
|
||||
return setgroups(count, gids);
|
||||
}
|
||||
}
|
49
Userland/Libraries/LibC/grp.h
Normal file
49
Userland/Libraries/LibC/grp.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
struct group {
|
||||
char* gr_name;
|
||||
char* gr_passwd;
|
||||
gid_t gr_gid;
|
||||
char** gr_mem;
|
||||
};
|
||||
|
||||
struct group* getgrent();
|
||||
void setgrent();
|
||||
void endgrent();
|
||||
struct group* getgrnam(const char* name);
|
||||
struct group* getgrgid(gid_t);
|
||||
|
||||
int initgroups(const char* user, gid_t);
|
||||
|
||||
__END_DECLS
|
40
Userland/Libraries/LibC/iconv.h
Normal file
40
Userland/Libraries/LibC/iconv.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
typedef void* iconv_t;
|
||||
|
||||
extern iconv_t iconv_open(const char* tocode, const char* fromcode);
|
||||
extern size_t iconv(iconv_t, char** inbuf, size_t* inbytesleft, char** outbuf, size_t* outbytesleft);
|
||||
extern int iconv_close(iconv_t);
|
||||
|
||||
__END_DECLS
|
70
Userland/Libraries/LibC/inttypes.h
Normal file
70
Userland/Libraries/LibC/inttypes.h
Normal file
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <bits/stdint.h>
|
||||
|
||||
#define PRId8 "d"
|
||||
#define PRId16 "d"
|
||||
#define PRId32 "d"
|
||||
#define PRId64 "lld"
|
||||
#define PRIi8 "d"
|
||||
#define PRIi16 "d"
|
||||
#define PRIi32 "d"
|
||||
#define PRIi64 "lld"
|
||||
#define PRIu8 "u"
|
||||
#define PRIo8 "o"
|
||||
#define PRIo16 "o"
|
||||
#define PRIo32 "o"
|
||||
#define PRIo64 "llo"
|
||||
#define PRIu16 "u"
|
||||
#define PRIu32 "u"
|
||||
#define PRIu64 "llu"
|
||||
#define PRIx8 "b"
|
||||
#define PRIx16 "w"
|
||||
#define PRIx32 "x"
|
||||
#define PRIX32 "X"
|
||||
#define PRIx64 "llx"
|
||||
#define PRIX64 "llX"
|
||||
|
||||
#define __PRI64_PREFIX "ll"
|
||||
#define __PRIPTR_PREFIX
|
||||
|
||||
#define PRIdPTR __PRIPTR_PREFIX "d"
|
||||
#define PRIiPTR __PRIPTR_PREFIX "i"
|
||||
#define PRIXPTR __PRIPTR_PREFIX "X"
|
||||
|
||||
#define PRIdMAX __PRI64_PREFIX "d"
|
||||
#define PRIoMAX __PRI64_PREFIX "o"
|
||||
#define PRIuMAX __PRI64_PREFIX "u"
|
||||
|
||||
#define SCNdMAX __PRI64_PREFIX "d"
|
||||
#define SCNoMAX __PRI64_PREFIX "o"
|
||||
#define SCNuMAX __PRI64_PREFIX "u"
|
||||
|
||||
#define SCNu64 __PRI64_PREFIX "u"
|
||||
#define SCNd64 __PRI64_PREFIX "d"
|
44
Userland/Libraries/LibC/ioctl.cpp
Normal file
44
Userland/Libraries/LibC/ioctl.cpp
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <Kernel/API/Syscall.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
int ioctl(int fd, unsigned request, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, request);
|
||||
unsigned arg = va_arg(ap, unsigned);
|
||||
int rc = syscall(SC_ioctl, fd, request, arg);
|
||||
va_end(ap);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
}
|
48
Userland/Libraries/LibC/libcinit.cpp
Normal file
48
Userland/Libraries/LibC/libcinit.cpp
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <AK/Types.h>
|
||||
#include <assert.h>
|
||||
#include <sys/internals.h>
|
||||
#include <unistd.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
#ifdef NO_TLS
|
||||
int errno;
|
||||
#else
|
||||
__thread int errno;
|
||||
#endif
|
||||
char** environ;
|
||||
bool __environ_is_malloced;
|
||||
bool __stdio_is_initialized;
|
||||
|
||||
void __libc_init()
|
||||
{
|
||||
__malloc_init();
|
||||
__stdio_init();
|
||||
}
|
||||
}
|
84
Userland/Libraries/LibC/libgen.cpp
Normal file
84
Userland/Libraries/LibC/libgen.cpp
Normal file
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2020, Sergey Bugaev <bugaevc@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <AK/Assertions.h>
|
||||
#include <libgen.h>
|
||||
#include <string.h>
|
||||
|
||||
static char dot[] = ".";
|
||||
static char slash[] = "/";
|
||||
|
||||
char* dirname(char* path)
|
||||
{
|
||||
if (path == nullptr)
|
||||
return dot;
|
||||
|
||||
int len = strlen(path);
|
||||
if (len == 0)
|
||||
return dot;
|
||||
|
||||
while (len > 1 && path[len - 1] == '/') {
|
||||
path[len - 1] = 0;
|
||||
len--;
|
||||
}
|
||||
|
||||
char* last_slash = strrchr(path, '/');
|
||||
if (last_slash == nullptr)
|
||||
return dot;
|
||||
|
||||
if (last_slash == path)
|
||||
return slash;
|
||||
|
||||
*last_slash = 0;
|
||||
return path;
|
||||
}
|
||||
|
||||
char* basename(char* path)
|
||||
{
|
||||
if (path == nullptr)
|
||||
return dot;
|
||||
|
||||
int len = strlen(path);
|
||||
if (len == 0)
|
||||
return dot;
|
||||
|
||||
while (len > 1 && path[len - 1] == '/') {
|
||||
path[len - 1] = 0;
|
||||
len--;
|
||||
}
|
||||
|
||||
char* last_slash = strrchr(path, '/');
|
||||
if (last_slash == nullptr)
|
||||
return path;
|
||||
|
||||
if (len == 1) {
|
||||
ASSERT(last_slash == path);
|
||||
ASSERT(path[0] == '/');
|
||||
return slash;
|
||||
}
|
||||
|
||||
return last_slash + 1;
|
||||
}
|
36
Userland/Libraries/LibC/libgen.h
Normal file
36
Userland/Libraries/LibC/libgen.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2020, Sergey Bugaev <bugaevc@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
char* dirname(char* path);
|
||||
char* basename(char* path);
|
||||
|
||||
__END_DECLS
|
78
Userland/Libraries/LibC/limits.h
Normal file
78
Userland/Libraries/LibC/limits.h
Normal file
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <bits/stdint.h>
|
||||
|
||||
#ifndef PAGE_SIZE
|
||||
# define PAGE_SIZE 4096
|
||||
#endif
|
||||
|
||||
#define PATH_MAX 4096
|
||||
#if !defined MAXPATHLEN && defined PATH_MAX
|
||||
# define MAXPATHLEN PATH_MAX
|
||||
#endif
|
||||
|
||||
#define NAME_MAX 255
|
||||
|
||||
#define PIPE_BUF 4096
|
||||
|
||||
#define INT_MAX INT32_MAX
|
||||
#define INT_MIN INT32_MIN
|
||||
|
||||
#define UINT_MAX UINT32_MAX
|
||||
#define UINT_MIN UINT32_MIN
|
||||
|
||||
#define CHAR_BIT 8
|
||||
#define SCHAR_MIN (-128)
|
||||
#define SCHAR_MAX 127
|
||||
#define UCHAR_MAX 255
|
||||
|
||||
#define LONG_MAX 2147483647L
|
||||
#define LONG_MIN (-LONG_MAX - 1L)
|
||||
|
||||
#define ULONG_MAX 4294967295UL
|
||||
|
||||
#define LONG_LONG_MAX 9223372036854775807LL
|
||||
#define LONG_LONG_MIN (-LONG_LONG_MAX - 1LL)
|
||||
|
||||
#define ULONG_LONG_MAX 18446744073709551615ULL
|
||||
|
||||
#define CHAR_MIN SCHAR_MIN
|
||||
#define CHAR_MAX SCHAR_MAX
|
||||
|
||||
#define MB_LEN_MAX 16
|
||||
|
||||
#define ARG_MAX 65536
|
||||
|
||||
#define PTHREAD_STACK_MIN 65536
|
||||
|
||||
#define SSIZE_MAX 2147483647
|
||||
|
||||
#ifdef __USE_POSIX
|
||||
# include <bits/posix1_lim.h>
|
||||
#endif
|
78
Userland/Libraries/LibC/locale.cpp
Normal file
78
Userland/Libraries/LibC/locale.cpp
Normal file
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <AK/LogStream.h>
|
||||
#include <assert.h>
|
||||
#include <locale.h>
|
||||
#include <stdio.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
static char default_decimal_point[] = ".";
|
||||
static char default_thousands_sep[] = ",";
|
||||
static char default_grouping[] = "\x03\x03";
|
||||
|
||||
static char default_empty_string[] = "";
|
||||
static char default_empty_value = 127;
|
||||
|
||||
static struct lconv default_locale = {
|
||||
default_decimal_point,
|
||||
default_thousands_sep,
|
||||
default_grouping,
|
||||
default_empty_string,
|
||||
default_empty_string,
|
||||
default_empty_string,
|
||||
default_empty_string,
|
||||
default_empty_string,
|
||||
default_empty_string,
|
||||
default_empty_string,
|
||||
default_empty_value,
|
||||
default_empty_value,
|
||||
default_empty_value,
|
||||
default_empty_value,
|
||||
default_empty_value,
|
||||
default_empty_value,
|
||||
default_empty_value,
|
||||
default_empty_value,
|
||||
default_empty_value,
|
||||
default_empty_value,
|
||||
default_empty_value,
|
||||
default_empty_value,
|
||||
default_empty_value,
|
||||
default_empty_value
|
||||
};
|
||||
|
||||
char* setlocale(int category, const char* locale)
|
||||
{
|
||||
dbgln("FIXME(LibC): setlocale({}, '{}')", category, locale);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
struct lconv* localeconv()
|
||||
{
|
||||
return &default_locale;
|
||||
}
|
||||
}
|
72
Userland/Libraries/LibC/locale.h
Normal file
72
Userland/Libraries/LibC/locale.h
Normal file
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
enum {
|
||||
LC_ALL,
|
||||
LC_NUMERIC,
|
||||
LC_CTYPE,
|
||||
LC_COLLATE,
|
||||
LC_TIME,
|
||||
LC_MONETARY,
|
||||
};
|
||||
|
||||
struct lconv {
|
||||
char* decimal_point;
|
||||
char* thousands_sep;
|
||||
char* grouping;
|
||||
char* int_curr_symbol;
|
||||
char* currency_symbol;
|
||||
char* mon_decimal_point;
|
||||
char* mon_thousands_sep;
|
||||
char* mon_grouping;
|
||||
char* positive_sign;
|
||||
char* negative_sign;
|
||||
char int_frac_digits;
|
||||
char frac_digits;
|
||||
char p_cs_precedes;
|
||||
char p_sep_by_space;
|
||||
char n_cs_precedes;
|
||||
char n_sep_by_space;
|
||||
char p_sign_posn;
|
||||
char n_sign_posn;
|
||||
char int_p_cs_precedes;
|
||||
char int_p_sep_by_space;
|
||||
char int_n_cs_precedes;
|
||||
char int_n_sep_by_space;
|
||||
char int_p_sign_posn;
|
||||
char int_n_sign_posn;
|
||||
};
|
||||
|
||||
struct lconv* localeconv();
|
||||
char* setlocale(int category, const char* locale);
|
||||
|
||||
__END_DECLS
|
472
Userland/Libraries/LibC/malloc.cpp
Normal file
472
Userland/Libraries/LibC/malloc.cpp
Normal file
|
@ -0,0 +1,472 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <AK/InlineLinkedList.h>
|
||||
#include <AK/LogStream.h>
|
||||
#include <AK/ScopedValueRollback.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <LibThread/Lock.h>
|
||||
#include <assert.h>
|
||||
#include <mallocdefs.h>
|
||||
#include <serenity.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/internals.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
// FIXME: Thread safety.
|
||||
|
||||
//#define MALLOC_DEBUG
|
||||
#define RECYCLE_BIG_ALLOCATIONS
|
||||
|
||||
#define PAGE_ROUND_UP(x) ((((size_t)(x)) + PAGE_SIZE - 1) & (~(PAGE_SIZE - 1)))
|
||||
|
||||
ALWAYS_INLINE static void ue_notify_malloc(const void* ptr, size_t size)
|
||||
{
|
||||
send_secret_data_to_userspace_emulator(1, size, (FlatPtr)ptr);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE static void ue_notify_free(const void* ptr)
|
||||
{
|
||||
send_secret_data_to_userspace_emulator(2, (FlatPtr)ptr, 0);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE static void ue_notify_realloc(const void* ptr, size_t size)
|
||||
{
|
||||
send_secret_data_to_userspace_emulator(3, size, (FlatPtr)ptr);
|
||||
}
|
||||
|
||||
static LibThread::Lock& malloc_lock()
|
||||
{
|
||||
static u32 lock_storage[sizeof(LibThread::Lock) / sizeof(u32)];
|
||||
return *reinterpret_cast<LibThread::Lock*>(&lock_storage);
|
||||
}
|
||||
|
||||
constexpr size_t number_of_chunked_blocks_to_keep_around_per_size_class = 4;
|
||||
constexpr size_t number_of_big_blocks_to_keep_around_per_size_class = 8;
|
||||
|
||||
static bool s_log_malloc = false;
|
||||
static bool s_scrub_malloc = true;
|
||||
static bool s_scrub_free = true;
|
||||
static bool s_profiling = false;
|
||||
|
||||
struct MallocStats {
|
||||
size_t number_of_malloc_calls;
|
||||
|
||||
size_t number_of_big_allocator_hits;
|
||||
size_t number_of_big_allocator_purge_hits;
|
||||
size_t number_of_big_allocs;
|
||||
|
||||
size_t number_of_empty_block_hits;
|
||||
size_t number_of_empty_block_purge_hits;
|
||||
size_t number_of_block_allocs;
|
||||
size_t number_of_blocks_full;
|
||||
|
||||
size_t number_of_free_calls;
|
||||
|
||||
size_t number_of_big_allocator_keeps;
|
||||
size_t number_of_big_allocator_frees;
|
||||
|
||||
size_t number_of_freed_full_blocks;
|
||||
size_t number_of_keeps;
|
||||
size_t number_of_frees;
|
||||
};
|
||||
static MallocStats g_malloc_stats = {};
|
||||
|
||||
struct Allocator {
|
||||
size_t size { 0 };
|
||||
size_t block_count { 0 };
|
||||
size_t empty_block_count { 0 };
|
||||
ChunkedBlock* empty_blocks[number_of_chunked_blocks_to_keep_around_per_size_class] { nullptr };
|
||||
InlineLinkedList<ChunkedBlock> usable_blocks;
|
||||
InlineLinkedList<ChunkedBlock> full_blocks;
|
||||
};
|
||||
|
||||
struct BigAllocator {
|
||||
Vector<BigAllocationBlock*, number_of_big_blocks_to_keep_around_per_size_class> blocks;
|
||||
};
|
||||
|
||||
// Allocators will be initialized in __malloc_init.
|
||||
// We can not rely on global constructors to initialize them,
|
||||
// because they must be initialized before other global constructors
|
||||
// are run. Similarly, we can not allow global destructors to destruct
|
||||
// them. We could have used AK::NeverDestoyed to prevent the latter,
|
||||
// but it would have not helped with the former.
|
||||
static u8 g_allocators_storage[sizeof(Allocator) * num_size_classes];
|
||||
static u8 g_big_allocators_storage[sizeof(BigAllocator)];
|
||||
|
||||
static inline Allocator (&allocators())[num_size_classes]
|
||||
{
|
||||
return reinterpret_cast<Allocator(&)[num_size_classes]>(g_allocators_storage);
|
||||
}
|
||||
|
||||
static inline BigAllocator (&big_allocators())[1]
|
||||
{
|
||||
return reinterpret_cast<BigAllocator(&)[1]>(g_big_allocators_storage);
|
||||
}
|
||||
|
||||
static Allocator* allocator_for_size(size_t size, size_t& good_size)
|
||||
{
|
||||
for (size_t i = 0; size_classes[i]; ++i) {
|
||||
if (size <= size_classes[i]) {
|
||||
good_size = size_classes[i];
|
||||
return &allocators()[i];
|
||||
}
|
||||
}
|
||||
good_size = PAGE_ROUND_UP(size);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#ifdef RECYCLE_BIG_ALLOCATIONS
|
||||
static BigAllocator* big_allocator_for_size(size_t size)
|
||||
{
|
||||
if (size == 65536)
|
||||
return &big_allocators()[0];
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
|
||||
static void* os_alloc(size_t size, const char* name)
|
||||
{
|
||||
auto* ptr = serenity_mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0, ChunkedBlock::block_size, name);
|
||||
ASSERT(ptr != MAP_FAILED);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static void os_free(void* ptr, size_t size)
|
||||
{
|
||||
int rc = munmap(ptr, size);
|
||||
assert(rc == 0);
|
||||
}
|
||||
|
||||
static void* malloc_impl(size_t size)
|
||||
{
|
||||
LOCKER(malloc_lock());
|
||||
|
||||
if (s_log_malloc)
|
||||
dbgprintf("LibC: malloc(%zu)\n", size);
|
||||
|
||||
if (!size)
|
||||
return nullptr;
|
||||
|
||||
g_malloc_stats.number_of_malloc_calls++;
|
||||
|
||||
size_t good_size;
|
||||
auto* allocator = allocator_for_size(size, good_size);
|
||||
|
||||
if (!allocator) {
|
||||
size_t real_size = round_up_to_power_of_two(sizeof(BigAllocationBlock) + size, ChunkedBlock::block_size);
|
||||
#ifdef RECYCLE_BIG_ALLOCATIONS
|
||||
if (auto* allocator = big_allocator_for_size(real_size)) {
|
||||
if (!allocator->blocks.is_empty()) {
|
||||
g_malloc_stats.number_of_big_allocator_hits++;
|
||||
auto* block = allocator->blocks.take_last();
|
||||
int rc = madvise(block, real_size, MADV_SET_NONVOLATILE);
|
||||
bool this_block_was_purged = rc == 1;
|
||||
if (rc < 0) {
|
||||
perror("madvise");
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
if (mprotect(block, real_size, PROT_READ | PROT_WRITE) < 0) {
|
||||
perror("mprotect");
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
if (this_block_was_purged) {
|
||||
g_malloc_stats.number_of_big_allocator_purge_hits++;
|
||||
new (block) BigAllocationBlock(real_size);
|
||||
}
|
||||
|
||||
ue_notify_malloc(&block->m_slot[0], size);
|
||||
return &block->m_slot[0];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
g_malloc_stats.number_of_big_allocs++;
|
||||
auto* block = (BigAllocationBlock*)os_alloc(real_size, "malloc: BigAllocationBlock");
|
||||
new (block) BigAllocationBlock(real_size);
|
||||
ue_notify_malloc(&block->m_slot[0], size);
|
||||
return &block->m_slot[0];
|
||||
}
|
||||
|
||||
ChunkedBlock* block = nullptr;
|
||||
|
||||
for (block = allocator->usable_blocks.head(); block; block = block->next()) {
|
||||
if (block->free_chunks())
|
||||
break;
|
||||
}
|
||||
|
||||
if (!block && allocator->empty_block_count) {
|
||||
g_malloc_stats.number_of_empty_block_hits++;
|
||||
block = allocator->empty_blocks[--allocator->empty_block_count];
|
||||
int rc = madvise(block, ChunkedBlock::block_size, MADV_SET_NONVOLATILE);
|
||||
bool this_block_was_purged = rc == 1;
|
||||
if (rc < 0) {
|
||||
perror("madvise");
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
rc = mprotect(block, ChunkedBlock::block_size, PROT_READ | PROT_WRITE);
|
||||
if (rc < 0) {
|
||||
perror("mprotect");
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
if (this_block_was_purged) {
|
||||
g_malloc_stats.number_of_empty_block_purge_hits++;
|
||||
new (block) ChunkedBlock(good_size);
|
||||
}
|
||||
allocator->usable_blocks.append(block);
|
||||
}
|
||||
|
||||
if (!block) {
|
||||
g_malloc_stats.number_of_block_allocs++;
|
||||
char buffer[64];
|
||||
snprintf(buffer, sizeof(buffer), "malloc: ChunkedBlock(%zu)", good_size);
|
||||
block = (ChunkedBlock*)os_alloc(ChunkedBlock::block_size, buffer);
|
||||
new (block) ChunkedBlock(good_size);
|
||||
allocator->usable_blocks.append(block);
|
||||
++allocator->block_count;
|
||||
}
|
||||
|
||||
--block->m_free_chunks;
|
||||
void* ptr = block->m_freelist;
|
||||
ASSERT(ptr);
|
||||
block->m_freelist = block->m_freelist->next;
|
||||
if (block->is_full()) {
|
||||
g_malloc_stats.number_of_blocks_full++;
|
||||
#ifdef MALLOC_DEBUG
|
||||
dbgprintf("Block %p is now full in size class %zu\n", block, good_size);
|
||||
#endif
|
||||
allocator->usable_blocks.remove(block);
|
||||
allocator->full_blocks.append(block);
|
||||
}
|
||||
#ifdef MALLOC_DEBUG
|
||||
dbgprintf("LibC: allocated %p (chunk in block %p, size %zu)\n", ptr, block, block->bytes_per_chunk());
|
||||
#endif
|
||||
|
||||
if (s_scrub_malloc)
|
||||
memset(ptr, MALLOC_SCRUB_BYTE, block->m_size);
|
||||
|
||||
ue_notify_malloc(ptr, size);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static void free_impl(void* ptr)
|
||||
{
|
||||
ScopedValueRollback rollback(errno);
|
||||
|
||||
if (!ptr)
|
||||
return;
|
||||
|
||||
g_malloc_stats.number_of_free_calls++;
|
||||
|
||||
LOCKER(malloc_lock());
|
||||
|
||||
void* block_base = (void*)((FlatPtr)ptr & ChunkedBlock::ChunkedBlock::block_mask);
|
||||
size_t magic = *(size_t*)block_base;
|
||||
|
||||
if (magic == MAGIC_BIGALLOC_HEADER) {
|
||||
auto* block = (BigAllocationBlock*)block_base;
|
||||
#ifdef RECYCLE_BIG_ALLOCATIONS
|
||||
if (auto* allocator = big_allocator_for_size(block->m_size)) {
|
||||
if (allocator->blocks.size() < number_of_big_blocks_to_keep_around_per_size_class) {
|
||||
g_malloc_stats.number_of_big_allocator_keeps++;
|
||||
allocator->blocks.append(block);
|
||||
size_t this_block_size = block->m_size;
|
||||
if (mprotect(block, this_block_size, PROT_NONE) < 0) {
|
||||
perror("mprotect");
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
if (madvise(block, this_block_size, MADV_SET_VOLATILE) != 0) {
|
||||
perror("madvise");
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
g_malloc_stats.number_of_big_allocator_frees++;
|
||||
os_free(block, block->m_size);
|
||||
return;
|
||||
}
|
||||
|
||||
assert(magic == MAGIC_PAGE_HEADER);
|
||||
auto* block = (ChunkedBlock*)block_base;
|
||||
|
||||
#ifdef MALLOC_DEBUG
|
||||
dbgprintf("LibC: freeing %p in allocator %p (size=%zu, used=%zu)\n", ptr, block, block->bytes_per_chunk(), block->used_chunks());
|
||||
#endif
|
||||
|
||||
if (s_scrub_free)
|
||||
memset(ptr, FREE_SCRUB_BYTE, block->bytes_per_chunk());
|
||||
|
||||
auto* entry = (FreelistEntry*)ptr;
|
||||
entry->next = block->m_freelist;
|
||||
block->m_freelist = entry;
|
||||
|
||||
if (block->is_full()) {
|
||||
size_t good_size;
|
||||
auto* allocator = allocator_for_size(block->m_size, good_size);
|
||||
#ifdef MALLOC_DEBUG
|
||||
dbgprintf("Block %p no longer full in size class %zu\n", block, good_size);
|
||||
#endif
|
||||
g_malloc_stats.number_of_freed_full_blocks++;
|
||||
allocator->full_blocks.remove(block);
|
||||
allocator->usable_blocks.prepend(block);
|
||||
}
|
||||
|
||||
++block->m_free_chunks;
|
||||
|
||||
if (!block->used_chunks()) {
|
||||
size_t good_size;
|
||||
auto* allocator = allocator_for_size(block->m_size, good_size);
|
||||
if (allocator->block_count < number_of_chunked_blocks_to_keep_around_per_size_class) {
|
||||
#ifdef MALLOC_DEBUG
|
||||
dbgprintf("Keeping block %p around for size class %zu\n", block, good_size);
|
||||
#endif
|
||||
g_malloc_stats.number_of_keeps++;
|
||||
allocator->usable_blocks.remove(block);
|
||||
allocator->empty_blocks[allocator->empty_block_count++] = block;
|
||||
mprotect(block, ChunkedBlock::block_size, PROT_NONE);
|
||||
madvise(block, ChunkedBlock::block_size, MADV_SET_VOLATILE);
|
||||
return;
|
||||
}
|
||||
#ifdef MALLOC_DEBUG
|
||||
dbgprintf("Releasing block %p for size class %zu\n", block, good_size);
|
||||
#endif
|
||||
g_malloc_stats.number_of_frees++;
|
||||
allocator->usable_blocks.remove(block);
|
||||
--allocator->block_count;
|
||||
os_free(block, ChunkedBlock::block_size);
|
||||
}
|
||||
}
|
||||
|
||||
[[gnu::flatten]] void* malloc(size_t size)
|
||||
{
|
||||
void* ptr = malloc_impl(size);
|
||||
if (s_profiling)
|
||||
perf_event(PERF_EVENT_MALLOC, size, reinterpret_cast<FlatPtr>(ptr));
|
||||
return ptr;
|
||||
}
|
||||
|
||||
[[gnu::flatten]] void free(void* ptr)
|
||||
{
|
||||
if (s_profiling)
|
||||
perf_event(PERF_EVENT_FREE, reinterpret_cast<FlatPtr>(ptr), 0);
|
||||
ue_notify_free(ptr);
|
||||
free_impl(ptr);
|
||||
}
|
||||
|
||||
void* calloc(size_t count, size_t size)
|
||||
{
|
||||
size_t new_size = count * size;
|
||||
auto* ptr = malloc(new_size);
|
||||
if (ptr)
|
||||
memset(ptr, 0, new_size);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
size_t malloc_size(void* ptr)
|
||||
{
|
||||
if (!ptr)
|
||||
return 0;
|
||||
LOCKER(malloc_lock());
|
||||
void* page_base = (void*)((FlatPtr)ptr & ChunkedBlock::block_mask);
|
||||
auto* header = (const CommonHeader*)page_base;
|
||||
auto size = header->m_size;
|
||||
if (header->m_magic == MAGIC_BIGALLOC_HEADER)
|
||||
size -= sizeof(CommonHeader);
|
||||
else
|
||||
ASSERT(header->m_magic == MAGIC_PAGE_HEADER);
|
||||
return size;
|
||||
}
|
||||
|
||||
void* realloc(void* ptr, size_t size)
|
||||
{
|
||||
if (!ptr)
|
||||
return malloc(size);
|
||||
if (!size)
|
||||
return nullptr;
|
||||
|
||||
LOCKER(malloc_lock());
|
||||
auto existing_allocation_size = malloc_size(ptr);
|
||||
|
||||
if (size <= existing_allocation_size) {
|
||||
ue_notify_realloc(ptr, size);
|
||||
return ptr;
|
||||
}
|
||||
auto* new_ptr = malloc(size);
|
||||
if (new_ptr) {
|
||||
memcpy(new_ptr, ptr, min(existing_allocation_size, size));
|
||||
free(ptr);
|
||||
}
|
||||
return new_ptr;
|
||||
}
|
||||
|
||||
void __malloc_init()
|
||||
{
|
||||
new (&malloc_lock()) LibThread::Lock();
|
||||
if (getenv("LIBC_NOSCRUB_MALLOC"))
|
||||
s_scrub_malloc = false;
|
||||
if (getenv("LIBC_NOSCRUB_FREE"))
|
||||
s_scrub_free = false;
|
||||
if (getenv("LIBC_LOG_MALLOC"))
|
||||
s_log_malloc = true;
|
||||
if (getenv("LIBC_PROFILE_MALLOC"))
|
||||
s_profiling = true;
|
||||
|
||||
for (size_t i = 0; i < num_size_classes; ++i) {
|
||||
new (&allocators()[i]) Allocator();
|
||||
allocators()[i].size = size_classes[i];
|
||||
}
|
||||
|
||||
new (&big_allocators()[0])(BigAllocator);
|
||||
}
|
||||
|
||||
void serenity_dump_malloc_stats()
|
||||
{
|
||||
dbgln("# malloc() calls: {}", g_malloc_stats.number_of_malloc_calls);
|
||||
dbgln();
|
||||
dbgln("big alloc hits: {}", g_malloc_stats.number_of_big_allocator_hits);
|
||||
dbgln("big alloc hits that were purged: {}", g_malloc_stats.number_of_big_allocator_purge_hits);
|
||||
dbgln("big allocs: {}", g_malloc_stats.number_of_big_allocs);
|
||||
dbgln();
|
||||
dbgln("empty block hits: {}", g_malloc_stats.number_of_empty_block_hits);
|
||||
dbgln("empty block hits that were purged: {}", g_malloc_stats.number_of_empty_block_purge_hits);
|
||||
dbgln("block allocs: {}", g_malloc_stats.number_of_block_allocs);
|
||||
dbgln("filled blocks: {}", g_malloc_stats.number_of_blocks_full);
|
||||
dbgln();
|
||||
dbgln("# free() calls: {}", g_malloc_stats.number_of_free_calls);
|
||||
dbgln();
|
||||
dbgln("big alloc keeps: {}", g_malloc_stats.number_of_big_allocator_keeps);
|
||||
dbgln("big alloc frees: {}", g_malloc_stats.number_of_big_allocator_frees);
|
||||
dbgln();
|
||||
dbgln("full block frees: {}", g_malloc_stats.number_of_freed_full_blocks);
|
||||
dbgln("number of keeps: {}", g_malloc_stats.number_of_keeps);
|
||||
dbgln("number of frees: {}", g_malloc_stats.number_of_frees);
|
||||
}
|
||||
}
|
95
Userland/Libraries/LibC/mallocdefs.h
Normal file
95
Userland/Libraries/LibC/mallocdefs.h
Normal file
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/InlineLinkedList.h>
|
||||
#include <AK/Types.h>
|
||||
|
||||
#define MAGIC_PAGE_HEADER 0x42657274 // 'Bert'
|
||||
#define MAGIC_BIGALLOC_HEADER 0x42697267 // 'Birg'
|
||||
#define MALLOC_SCRUB_BYTE 0xdc
|
||||
#define FREE_SCRUB_BYTE 0xed
|
||||
|
||||
static constexpr unsigned short size_classes[] = { 8, 16, 32, 64, 128, 256, 500, 1016, 2032, 4088, 8184, 16376, 32752, 0 };
|
||||
static constexpr size_t num_size_classes = (sizeof(size_classes) / sizeof(unsigned short)) - 1;
|
||||
|
||||
struct CommonHeader {
|
||||
size_t m_magic;
|
||||
size_t m_size;
|
||||
};
|
||||
|
||||
struct BigAllocationBlock : public CommonHeader {
|
||||
BigAllocationBlock(size_t size)
|
||||
{
|
||||
m_magic = MAGIC_BIGALLOC_HEADER;
|
||||
m_size = size;
|
||||
}
|
||||
unsigned char* m_slot[0];
|
||||
};
|
||||
|
||||
struct FreelistEntry {
|
||||
FreelistEntry* next;
|
||||
};
|
||||
|
||||
struct ChunkedBlock
|
||||
: public CommonHeader
|
||||
, public InlineLinkedListNode<ChunkedBlock> {
|
||||
|
||||
static constexpr size_t block_size = 64 * KiB;
|
||||
static constexpr size_t block_mask = ~(block_size - 1);
|
||||
|
||||
ChunkedBlock(size_t bytes_per_chunk)
|
||||
{
|
||||
m_magic = MAGIC_PAGE_HEADER;
|
||||
m_size = bytes_per_chunk;
|
||||
m_free_chunks = chunk_capacity();
|
||||
m_freelist = (FreelistEntry*)chunk(0);
|
||||
for (size_t i = 0; i < chunk_capacity(); ++i) {
|
||||
auto* entry = (FreelistEntry*)chunk(i);
|
||||
if (i != chunk_capacity() - 1)
|
||||
entry->next = (FreelistEntry*)chunk(i + 1);
|
||||
else
|
||||
entry->next = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
ChunkedBlock* m_prev { nullptr };
|
||||
ChunkedBlock* m_next { nullptr };
|
||||
FreelistEntry* m_freelist { nullptr };
|
||||
size_t m_free_chunks { 0 };
|
||||
[[gnu::aligned(8)]] unsigned char m_slot[0];
|
||||
|
||||
void* chunk(size_t index)
|
||||
{
|
||||
return &m_slot[index * m_size];
|
||||
}
|
||||
bool is_full() const { return m_free_chunks == 0; }
|
||||
size_t bytes_per_chunk() const { return m_size; }
|
||||
size_t free_chunks() const { return m_free_chunks; }
|
||||
size_t used_chunks() const { return chunk_capacity() - m_free_chunks; }
|
||||
size_t chunk_capacity() const { return (block_size - sizeof(ChunkedBlock)) / m_size; }
|
||||
};
|
29
Userland/Libraries/LibC/memory.h
Normal file
29
Userland/Libraries/LibC/memory.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string.h>
|
111
Userland/Libraries/LibC/mman.cpp
Normal file
111
Userland/Libraries/LibC/mman.cpp
Normal file
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <Kernel/API/Syscall.h>
|
||||
#include <errno.h>
|
||||
#include <mman.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
void* serenity_mmap(void* addr, size_t size, int prot, int flags, int fd, off_t offset, size_t alignment, const char* name)
|
||||
{
|
||||
Syscall::SC_mmap_params params { (uintptr_t)addr, size, alignment, prot, flags, fd, offset, { name, name ? strlen(name) : 0 } };
|
||||
ssize_t rc = syscall(SC_mmap, ¶ms);
|
||||
if (rc < 0 && -rc < EMAXERRNO) {
|
||||
errno = -rc;
|
||||
return MAP_FAILED;
|
||||
}
|
||||
return (void*)rc;
|
||||
}
|
||||
|
||||
void* mmap(void* addr, size_t size, int prot, int flags, int fd, off_t offset)
|
||||
{
|
||||
return serenity_mmap(addr, size, prot, flags, fd, offset, PAGE_SIZE, nullptr);
|
||||
}
|
||||
|
||||
void* mmap_with_name(void* addr, size_t size, int prot, int flags, int fd, off_t offset, const char* name)
|
||||
{
|
||||
return serenity_mmap(addr, size, prot, flags, fd, offset, PAGE_SIZE, name);
|
||||
}
|
||||
|
||||
void* mremap(void* old_address, size_t old_size, size_t new_size, int flags)
|
||||
{
|
||||
Syscall::SC_mremap_params params { (uintptr_t)old_address, old_size, new_size, flags };
|
||||
ssize_t rc = syscall(SC_mremap, ¶ms);
|
||||
if (rc < 0 && -rc < EMAXERRNO) {
|
||||
errno = -rc;
|
||||
return MAP_FAILED;
|
||||
}
|
||||
return (void*)rc;
|
||||
}
|
||||
|
||||
int munmap(void* addr, size_t size)
|
||||
{
|
||||
int rc = syscall(SC_munmap, addr, size);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
|
||||
int mprotect(void* addr, size_t size, int prot)
|
||||
{
|
||||
int rc = syscall(SC_mprotect, addr, size, prot);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
|
||||
int set_mmap_name(void* addr, size_t size, const char* name)
|
||||
{
|
||||
if (!name) {
|
||||
errno = EFAULT;
|
||||
return -1;
|
||||
}
|
||||
Syscall::SC_set_mmap_name_params params { addr, size, { name, strlen(name) } };
|
||||
int rc = syscall(SC_set_mmap_name, ¶ms);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
|
||||
int madvise(void* address, size_t size, int advice)
|
||||
{
|
||||
int rc = syscall(SC_madvise, address, size, advice);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
|
||||
int minherit(void* address, size_t size, int inherit)
|
||||
{
|
||||
int rc = syscall(SC_minherit, address, size, inherit);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
|
||||
void* allocate_tls(size_t size)
|
||||
{
|
||||
int rc = syscall(SC_allocate_tls, size);
|
||||
if (rc < 0 && -rc < EMAXERRNO) {
|
||||
errno = -rc;
|
||||
return MAP_FAILED;
|
||||
}
|
||||
return (void*)rc;
|
||||
}
|
||||
}
|
67
Userland/Libraries/LibC/mman.h
Normal file
67
Userland/Libraries/LibC/mman.h
Normal file
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#define MAP_FILE 0x00
|
||||
#define MAP_SHARED 0x01
|
||||
#define MAP_PRIVATE 0x02
|
||||
#define MAP_FIXED 0x10
|
||||
#define MAP_ANONYMOUS 0x20
|
||||
#define MAP_ANON MAP_ANONYMOUS
|
||||
#define MAP_STACK 0x40
|
||||
#define MAP_NORESERVE 0x80
|
||||
|
||||
#define PROT_READ 0x1
|
||||
#define PROT_WRITE 0x2
|
||||
#define PROT_EXEC 0x4
|
||||
#define PROT_NONE 0x0
|
||||
|
||||
#define MAP_FAILED ((void*)-1)
|
||||
|
||||
#define MADV_SET_VOLATILE 0x100
|
||||
#define MADV_SET_NONVOLATILE 0x200
|
||||
#define MADV_GET_VOLATILE 0x400
|
||||
|
||||
#define MAP_INHERIT_ZERO 1
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
void* mmap(void* addr, size_t, int prot, int flags, int fd, off_t);
|
||||
void* mmap_with_name(void* addr, size_t, int prot, int flags, int fd, off_t, const char* name);
|
||||
void* serenity_mmap(void* addr, size_t, int prot, int flags, int fd, off_t, size_t alignment, const char* name);
|
||||
void* mremap(void* old_address, size_t old_size, size_t new_size, int flags);
|
||||
int munmap(void*, size_t);
|
||||
int mprotect(void*, size_t, int prot);
|
||||
int set_mmap_name(void*, size_t, const char*);
|
||||
int madvise(void*, size_t, int advice);
|
||||
int minherit(void*, size_t, int inherit);
|
||||
void* allocate_tls(size_t);
|
||||
|
||||
__END_DECLS
|
37
Userland/Libraries/LibC/mntent.cpp
Normal file
37
Userland/Libraries/LibC/mntent.cpp
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <mntent.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
struct mntent* getmntent(FILE*)
|
||||
{
|
||||
ASSERT_NOT_REACHED();
|
||||
return nullptr;
|
||||
}
|
||||
}
|
48
Userland/Libraries/LibC/mntent.h
Normal file
48
Userland/Libraries/LibC/mntent.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
#define MOUNTED "/etc/mtab"
|
||||
#define MNTTAB "/etc/fstab"
|
||||
|
||||
struct mntent {
|
||||
char* mnt_fsname;
|
||||
char* mnt_dir;
|
||||
char* mnt_type;
|
||||
char* mnt_opts;
|
||||
int mnt_freq;
|
||||
int mnt_passno;
|
||||
};
|
||||
|
||||
struct mntent* getmntent(FILE* stream);
|
||||
|
||||
__END_DECLS
|
71
Userland/Libraries/LibC/net/if.h
Normal file
71
Userland/Libraries/LibC/net/if.h
Normal file
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
struct ifreq {
|
||||
#define IFNAMSIZ 16
|
||||
char ifr_name[IFNAMSIZ];
|
||||
union {
|
||||
struct sockaddr ifru_addr;
|
||||
struct sockaddr ifru_dstaddr;
|
||||
struct sockaddr ifru_broadaddr;
|
||||
struct sockaddr ifru_netmask;
|
||||
struct sockaddr ifru_hwaddr;
|
||||
short ifru_flags;
|
||||
int ifru_metric;
|
||||
int64_t ifru_vnetid;
|
||||
uint64_t ifru_media;
|
||||
void* ifru_data;
|
||||
unsigned int ifru_index;
|
||||
} ifr_ifru;
|
||||
|
||||
// clang-format off
|
||||
#define ifr_addr ifr_ifru.ifru_addr // address
|
||||
#define ifr_dstaddr ifr_ifru.ifru_dstaddr // other end of p-to-p link
|
||||
#define ifr_broadaddr ifr_ifru.ifru_broadaddr // broadcast address
|
||||
#define ifr_netmask ifr_ifru.ifru_netmask // network mask
|
||||
#define ifr_flags ifr_ifru.ifru_flags // flags
|
||||
#define ifr_metric ifr_ifru.ifru_metric // metric
|
||||
#define ifr_mtu ifr_ifru.ifru_metric // mtu (overload)
|
||||
#define ifr_hardmtu ifr_ifru.ifru_metric // hardmtu (overload)
|
||||
#define ifr_media ifr_ifru.ifru_media // media options
|
||||
#define ifr_rdomainid ifr_ifru.ifru_metric // VRF instance (overload)
|
||||
#define ifr_vnetid ifr_ifru.ifru_vnetid // Virtual Net Id
|
||||
#define ifr_ttl ifr_ifru.ifru_metric // tunnel TTL (overload)
|
||||
#define ifr_data ifr_ifru.ifru_data // for use by interface
|
||||
#define ifr_index ifr_ifru.ifru_index // interface index
|
||||
#define ifr_llprio ifr_ifru.ifru_metric // link layer priority
|
||||
#define ifr_hwaddr ifr_ifru.ifru_hwaddr // MAC address
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
__END_DECLS
|
40
Userland/Libraries/LibC/net/route.h
Normal file
40
Userland/Libraries/LibC/net/route.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Marios Prokopakis <mariosprokopakis@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <sys/socket.h>
|
||||
|
||||
struct rtentry {
|
||||
struct sockaddr rt_gateway; /* the gateway address */
|
||||
struct sockaddr rt_genmask; /* the target network mask */
|
||||
unsigned short int rt_flags;
|
||||
char* rt_dev;
|
||||
/* FIXME: complete the struct */
|
||||
};
|
||||
|
||||
#define RTF_UP 0x1 /* do not delete the route */
|
||||
#define RTF_GATEWAY 0x2 /* the route is a gateway and not an end host */
|
590
Userland/Libraries/LibC/netdb.cpp
Normal file
590
Userland/Libraries/LibC/netdb.cpp
Normal file
|
@ -0,0 +1,590 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <AK/Assertions.h>
|
||||
#include <AK/ByteBuffer.h>
|
||||
#include <AK/ScopeGuard.h>
|
||||
#include <AK/String.h>
|
||||
#include <Kernel/Net/IPv4.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
int h_errno;
|
||||
|
||||
static hostent __gethostbyname_buffer;
|
||||
static in_addr_t __gethostbyname_address;
|
||||
static in_addr_t* __gethostbyname_address_list_buffer[2];
|
||||
|
||||
static hostent __gethostbyaddr_buffer;
|
||||
static in_addr_t* __gethostbyaddr_address_list_buffer[2];
|
||||
|
||||
// Get service entry buffers and file information for the getservent() family of functions.
|
||||
static FILE* services_file = nullptr;
|
||||
static const char* services_path = "/etc/services";
|
||||
|
||||
static bool fill_getserv_buffers(const char* line, ssize_t read);
|
||||
static servent __getserv_buffer;
|
||||
static String __getserv_name_buffer;
|
||||
static String __getserv_protocol_buffer;
|
||||
static int __getserv_port_buffer;
|
||||
static Vector<ByteBuffer> __getserv_alias_list_buffer;
|
||||
static Vector<char*> __getserv_alias_list;
|
||||
static bool keep_service_file_open = false;
|
||||
static ssize_t service_file_offset = 0;
|
||||
|
||||
// Get protocol entry buffers and file information for the getprotent() family of functions.
|
||||
static FILE* protocols_file = nullptr;
|
||||
static const char* protocols_path = "/etc/protocols";
|
||||
|
||||
static bool fill_getproto_buffers(const char* line, ssize_t read);
|
||||
static protoent __getproto_buffer;
|
||||
static String __getproto_name_buffer;
|
||||
static Vector<ByteBuffer> __getproto_alias_list_buffer;
|
||||
static Vector<char*> __getproto_alias_list;
|
||||
static int __getproto_protocol_buffer;
|
||||
static bool keep_protocols_file_open = false;
|
||||
static ssize_t protocol_file_offset = 0;
|
||||
|
||||
static int connect_to_lookup_server()
|
||||
{
|
||||
int fd = socket(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0);
|
||||
if (fd < 0) {
|
||||
perror("socket");
|
||||
return -1;
|
||||
}
|
||||
|
||||
sockaddr_un address {
|
||||
AF_LOCAL,
|
||||
"/tmp/portal/lookup"
|
||||
};
|
||||
|
||||
if (connect(fd, (const sockaddr*)&address, sizeof(address)) < 0) {
|
||||
perror("connect_to_lookup_server");
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
static String gethostbyname_name_buffer;
|
||||
|
||||
hostent* gethostbyname(const char* name)
|
||||
{
|
||||
auto ipv4_address = IPv4Address::from_string(name);
|
||||
|
||||
if (ipv4_address.has_value()) {
|
||||
gethostbyname_name_buffer = ipv4_address.value().to_string();
|
||||
__gethostbyname_buffer.h_name = const_cast<char*>(gethostbyname_name_buffer.characters());
|
||||
__gethostbyname_buffer.h_aliases = nullptr;
|
||||
__gethostbyname_buffer.h_addrtype = AF_INET;
|
||||
new (&__gethostbyname_address) IPv4Address(ipv4_address.value());
|
||||
__gethostbyname_address_list_buffer[0] = &__gethostbyname_address;
|
||||
__gethostbyname_address_list_buffer[1] = nullptr;
|
||||
__gethostbyname_buffer.h_addr_list = (char**)__gethostbyname_address_list_buffer;
|
||||
__gethostbyname_buffer.h_length = 4;
|
||||
|
||||
return &__gethostbyname_buffer;
|
||||
}
|
||||
|
||||
int fd = connect_to_lookup_server();
|
||||
if (fd < 0)
|
||||
return nullptr;
|
||||
|
||||
auto close_fd_on_exit = ScopeGuard([fd] {
|
||||
close(fd);
|
||||
});
|
||||
|
||||
auto line = String::format("L%s\n", name);
|
||||
int nsent = write(fd, line.characters(), line.length());
|
||||
if (nsent < 0) {
|
||||
perror("write");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ASSERT((size_t)nsent == line.length());
|
||||
|
||||
char buffer[1024];
|
||||
int nrecv = read(fd, buffer, sizeof(buffer) - 1);
|
||||
if (nrecv < 0) {
|
||||
perror("recv");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!memcmp(buffer, "Not found.", sizeof("Not found.") - 1))
|
||||
return nullptr;
|
||||
|
||||
auto responses = String(buffer, nrecv).split('\n');
|
||||
if (responses.is_empty())
|
||||
return nullptr;
|
||||
|
||||
auto& response = responses[0];
|
||||
|
||||
int rc = inet_pton(AF_INET, response.characters(), &__gethostbyname_address);
|
||||
if (rc <= 0)
|
||||
return nullptr;
|
||||
|
||||
gethostbyname_name_buffer = name;
|
||||
__gethostbyname_buffer.h_name = const_cast<char*>(gethostbyname_name_buffer.characters());
|
||||
__gethostbyname_buffer.h_aliases = nullptr;
|
||||
__gethostbyname_buffer.h_addrtype = AF_INET;
|
||||
__gethostbyname_address_list_buffer[0] = &__gethostbyname_address;
|
||||
__gethostbyname_address_list_buffer[1] = nullptr;
|
||||
__gethostbyname_buffer.h_addr_list = (char**)__gethostbyname_address_list_buffer;
|
||||
__gethostbyname_buffer.h_length = 4;
|
||||
|
||||
return &__gethostbyname_buffer;
|
||||
}
|
||||
|
||||
static String gethostbyaddr_name_buffer;
|
||||
|
||||
hostent* gethostbyaddr(const void* addr, socklen_t addr_size, int type)
|
||||
{
|
||||
|
||||
if (type != AF_INET) {
|
||||
errno = EAFNOSUPPORT;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (addr_size < sizeof(in_addr)) {
|
||||
errno = EINVAL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int fd = connect_to_lookup_server();
|
||||
if (fd < 0)
|
||||
return nullptr;
|
||||
|
||||
auto close_fd_on_exit = ScopeGuard([fd] {
|
||||
close(fd);
|
||||
});
|
||||
|
||||
IPv4Address ipv4_address((const u8*)&((const in_addr*)addr)->s_addr);
|
||||
|
||||
auto line = String::format("R%d.%d.%d.%d.in-addr.arpa\n",
|
||||
ipv4_address[3],
|
||||
ipv4_address[2],
|
||||
ipv4_address[1],
|
||||
ipv4_address[0]);
|
||||
int nsent = write(fd, line.characters(), line.length());
|
||||
if (nsent < 0) {
|
||||
perror("write");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ASSERT((size_t)nsent == line.length());
|
||||
|
||||
char buffer[1024];
|
||||
int nrecv = read(fd, buffer, sizeof(buffer) - 1);
|
||||
if (nrecv < 0) {
|
||||
perror("recv");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!memcmp(buffer, "Not found.", sizeof("Not found.") - 1))
|
||||
return nullptr;
|
||||
|
||||
auto responses = String(buffer, nrecv).split('\n');
|
||||
if (responses.is_empty())
|
||||
return nullptr;
|
||||
|
||||
gethostbyaddr_name_buffer = responses[0];
|
||||
__gethostbyaddr_buffer.h_name = const_cast<char*>(gethostbyaddr_name_buffer.characters());
|
||||
__gethostbyaddr_buffer.h_aliases = nullptr;
|
||||
__gethostbyaddr_buffer.h_addrtype = AF_INET;
|
||||
// FIXME: Should we populate the hostent's address list here with a sockaddr_in for the provided host?
|
||||
__gethostbyaddr_address_list_buffer[0] = nullptr;
|
||||
__gethostbyaddr_buffer.h_addr_list = (char**)__gethostbyaddr_address_list_buffer;
|
||||
__gethostbyaddr_buffer.h_length = 4;
|
||||
|
||||
return &__gethostbyaddr_buffer;
|
||||
}
|
||||
|
||||
struct servent* getservent()
|
||||
{
|
||||
//If the services file is not open, attempt to open it and return null if it fails.
|
||||
if (!services_file) {
|
||||
services_file = fopen(services_path, "r");
|
||||
|
||||
if (!services_file) {
|
||||
perror("error opening services file");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (fseek(services_file, service_file_offset, SEEK_SET) != 0) {
|
||||
perror("error seeking file");
|
||||
fclose(services_file);
|
||||
return nullptr;
|
||||
}
|
||||
char* line = nullptr;
|
||||
size_t len = 0;
|
||||
ssize_t read;
|
||||
|
||||
auto free_line_on_exit = ScopeGuard([line] {
|
||||
if (line) {
|
||||
free(line);
|
||||
}
|
||||
});
|
||||
|
||||
// Read lines from services file until an actual service name is found.
|
||||
do {
|
||||
read = getline(&line, &len, services_file);
|
||||
service_file_offset += read;
|
||||
if (read > 0 && (line[0] >= 65 && line[0] <= 122)) {
|
||||
break;
|
||||
}
|
||||
} while (read != -1);
|
||||
if (read == -1) {
|
||||
fclose(services_file);
|
||||
services_file = nullptr;
|
||||
service_file_offset = 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
servent* service_entry = nullptr;
|
||||
if (!fill_getserv_buffers(line, read))
|
||||
return nullptr;
|
||||
|
||||
__getserv_buffer.s_name = const_cast<char*>(__getserv_name_buffer.characters());
|
||||
__getserv_buffer.s_port = __getserv_port_buffer;
|
||||
__getserv_buffer.s_proto = const_cast<char*>(__getserv_protocol_buffer.characters());
|
||||
|
||||
__getserv_alias_list.clear_with_capacity();
|
||||
__getserv_alias_list.ensure_capacity(__getserv_alias_list_buffer.size() + 1);
|
||||
for (auto& alias : __getserv_alias_list_buffer)
|
||||
__getserv_alias_list.unchecked_append(reinterpret_cast<char*>(alias.data()));
|
||||
__getserv_alias_list.unchecked_append(nullptr);
|
||||
|
||||
__getserv_buffer.s_aliases = __getserv_alias_list.data();
|
||||
service_entry = &__getserv_buffer;
|
||||
|
||||
if (!keep_service_file_open) {
|
||||
endservent();
|
||||
}
|
||||
return service_entry;
|
||||
}
|
||||
|
||||
struct servent* getservbyname(const char* name, const char* protocol)
|
||||
{
|
||||
bool previous_file_open_setting = keep_service_file_open;
|
||||
setservent(1);
|
||||
struct servent* current_service = nullptr;
|
||||
auto service_file_handler = ScopeGuard([previous_file_open_setting] {
|
||||
if (!previous_file_open_setting) {
|
||||
endservent();
|
||||
}
|
||||
});
|
||||
|
||||
while (true) {
|
||||
current_service = getservent();
|
||||
if (current_service == nullptr)
|
||||
break;
|
||||
else if (!protocol && strcmp(current_service->s_name, name) == 0)
|
||||
break;
|
||||
else if (strcmp(current_service->s_name, name) == 0 && strcmp(current_service->s_proto, protocol) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
return current_service;
|
||||
}
|
||||
|
||||
struct servent* getservbyport(int port, const char* protocol)
|
||||
{
|
||||
bool previous_file_open_setting = keep_service_file_open;
|
||||
setservent(1);
|
||||
struct servent* current_service = nullptr;
|
||||
auto service_file_handler = ScopeGuard([previous_file_open_setting] {
|
||||
if (!previous_file_open_setting) {
|
||||
endservent();
|
||||
}
|
||||
});
|
||||
while (true) {
|
||||
current_service = getservent();
|
||||
if (current_service == nullptr)
|
||||
break;
|
||||
else if (!protocol && current_service->s_port == port)
|
||||
break;
|
||||
else if (current_service->s_port == port && (strcmp(current_service->s_proto, protocol) == 0))
|
||||
break;
|
||||
}
|
||||
|
||||
return current_service;
|
||||
}
|
||||
|
||||
void setservent(int stay_open)
|
||||
{
|
||||
if (!services_file) {
|
||||
services_file = fopen(services_path, "r");
|
||||
|
||||
if (!services_file) {
|
||||
perror("error opening services file");
|
||||
return;
|
||||
}
|
||||
}
|
||||
rewind(services_file);
|
||||
keep_service_file_open = stay_open;
|
||||
service_file_offset = 0;
|
||||
}
|
||||
|
||||
void endservent()
|
||||
{
|
||||
if (!services_file) {
|
||||
return;
|
||||
}
|
||||
fclose(services_file);
|
||||
services_file = nullptr;
|
||||
}
|
||||
|
||||
// Fill the service entry buffer with the information contained
|
||||
// in the currently read line, returns true if successful,
|
||||
// false if failure occurs.
|
||||
static bool fill_getserv_buffers(const char* line, ssize_t read)
|
||||
{
|
||||
//Splitting the line by tab delimiter and filling the servent buffers name, port, and protocol members.
|
||||
String string_line = String(line, read);
|
||||
string_line.replace(" ", "\t", true);
|
||||
auto split_line = string_line.split('\t');
|
||||
|
||||
// This indicates an incorrect file format.
|
||||
// Services file entries should always at least contain
|
||||
// name and port/protocol, separated by tabs.
|
||||
if (split_line.size() < 2) {
|
||||
fprintf(stderr, "getservent(): malformed services file\n");
|
||||
return false;
|
||||
}
|
||||
__getserv_name_buffer = split_line[0];
|
||||
|
||||
auto port_protocol_split = String(split_line[1]).split('/');
|
||||
if (port_protocol_split.size() < 2) {
|
||||
fprintf(stderr, "getservent(): malformed services file\n");
|
||||
return false;
|
||||
}
|
||||
auto number = port_protocol_split[0].to_int();
|
||||
if (!number.has_value())
|
||||
return false;
|
||||
|
||||
__getserv_port_buffer = number.value();
|
||||
|
||||
// Remove any annoying whitespace at the end of the protocol.
|
||||
port_protocol_split[1].replace(" ", "", true);
|
||||
port_protocol_split[1].replace("\t", "", true);
|
||||
port_protocol_split[1].replace("\n", "", true);
|
||||
|
||||
__getserv_protocol_buffer = port_protocol_split[1];
|
||||
__getserv_alias_list_buffer.clear();
|
||||
|
||||
// If there are aliases for the service, we will fill the alias list buffer.
|
||||
if (split_line.size() > 2 && !split_line[2].starts_with('#')) {
|
||||
|
||||
for (size_t i = 2; i < split_line.size(); i++) {
|
||||
if (split_line[i].starts_with('#')) {
|
||||
break;
|
||||
}
|
||||
auto alias = split_line[i].to_byte_buffer();
|
||||
alias.append("\0", sizeof(char));
|
||||
__getserv_alias_list_buffer.append(alias);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
struct protoent* getprotoent()
|
||||
{
|
||||
// If protocols file isn't open, attempt to open and return null on failure.
|
||||
if (!protocols_file) {
|
||||
protocols_file = fopen(protocols_path, "r");
|
||||
|
||||
if (!protocols_file) {
|
||||
perror("error opening protocols file");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (fseek(protocols_file, protocol_file_offset, SEEK_SET) != 0) {
|
||||
perror("error seeking protocols file");
|
||||
fclose(protocols_file);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
char* line = nullptr;
|
||||
size_t len = 0;
|
||||
ssize_t read;
|
||||
|
||||
auto free_line_on_exit = ScopeGuard([line] {
|
||||
if (line) {
|
||||
free(line);
|
||||
}
|
||||
});
|
||||
|
||||
do {
|
||||
read = getline(&line, &len, protocols_file);
|
||||
protocol_file_offset += read;
|
||||
if (read > 0 && (line[0] >= 65 && line[0] <= 122)) {
|
||||
break;
|
||||
}
|
||||
} while (read != -1);
|
||||
|
||||
if (read == -1) {
|
||||
fclose(protocols_file);
|
||||
protocols_file = nullptr;
|
||||
protocol_file_offset = 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
struct protoent* protocol_entry = nullptr;
|
||||
if (!fill_getproto_buffers(line, read))
|
||||
return nullptr;
|
||||
|
||||
__getproto_buffer.p_name = const_cast<char*>(__getproto_name_buffer.characters());
|
||||
__getproto_buffer.p_proto = __getproto_protocol_buffer;
|
||||
|
||||
__getproto_alias_list.clear_with_capacity();
|
||||
__getproto_alias_list.ensure_capacity(__getproto_alias_list_buffer.size() + 1);
|
||||
for (auto& alias : __getproto_alias_list_buffer)
|
||||
__getproto_alias_list.unchecked_append(reinterpret_cast<char*>(alias.data()));
|
||||
__getserv_alias_list.unchecked_append(nullptr);
|
||||
|
||||
__getproto_buffer.p_aliases = __getproto_alias_list.data();
|
||||
protocol_entry = &__getproto_buffer;
|
||||
|
||||
if (!keep_protocols_file_open)
|
||||
endprotoent();
|
||||
|
||||
return protocol_entry;
|
||||
}
|
||||
|
||||
struct protoent* getprotobyname(const char* name)
|
||||
{
|
||||
bool previous_file_open_setting = keep_protocols_file_open;
|
||||
setprotoent(1);
|
||||
struct protoent* current_protocol = nullptr;
|
||||
auto protocol_file_handler = ScopeGuard([previous_file_open_setting] {
|
||||
if (!previous_file_open_setting) {
|
||||
endprotoent();
|
||||
}
|
||||
});
|
||||
|
||||
while (true) {
|
||||
current_protocol = getprotoent();
|
||||
if (current_protocol == nullptr)
|
||||
break;
|
||||
else if (strcmp(current_protocol->p_name, name) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
return current_protocol;
|
||||
}
|
||||
|
||||
struct protoent* getprotobynumber(int proto)
|
||||
{
|
||||
bool previous_file_open_setting = keep_protocols_file_open;
|
||||
setprotoent(1);
|
||||
struct protoent* current_protocol = nullptr;
|
||||
auto protocol_file_handler = ScopeGuard([previous_file_open_setting] {
|
||||
if (!previous_file_open_setting) {
|
||||
endprotoent();
|
||||
}
|
||||
});
|
||||
|
||||
while (true) {
|
||||
current_protocol = getprotoent();
|
||||
if (current_protocol == nullptr)
|
||||
break;
|
||||
else if (current_protocol->p_proto == proto)
|
||||
break;
|
||||
}
|
||||
|
||||
return current_protocol;
|
||||
}
|
||||
|
||||
void setprotoent(int stay_open)
|
||||
{
|
||||
if (!protocols_file) {
|
||||
protocols_file = fopen(protocols_path, "r");
|
||||
|
||||
if (!protocols_file) {
|
||||
perror("setprotoent(): error opening protocols file");
|
||||
return;
|
||||
}
|
||||
}
|
||||
rewind(protocols_file);
|
||||
keep_protocols_file_open = stay_open;
|
||||
protocol_file_offset = 0;
|
||||
}
|
||||
|
||||
void endprotoent()
|
||||
{
|
||||
if (!protocols_file) {
|
||||
return;
|
||||
}
|
||||
fclose(protocols_file);
|
||||
protocols_file = nullptr;
|
||||
}
|
||||
|
||||
static bool fill_getproto_buffers(const char* line, ssize_t read)
|
||||
{
|
||||
String string_line = String(line, read);
|
||||
string_line.replace(" ", "\t", true);
|
||||
auto split_line = string_line.split('\t');
|
||||
|
||||
// This indicates an incorrect file format. Protocols file entries should
|
||||
// always have at least a name and a protocol.
|
||||
if (split_line.size() < 2) {
|
||||
fprintf(stderr, "getprotoent(): malformed protocols file\n");
|
||||
return false;
|
||||
}
|
||||
__getproto_name_buffer = split_line[0];
|
||||
|
||||
auto number = split_line[1].to_int();
|
||||
if (!number.has_value())
|
||||
return false;
|
||||
|
||||
__getproto_protocol_buffer = number.value();
|
||||
|
||||
__getproto_alias_list_buffer.clear();
|
||||
|
||||
// If there are aliases for the protocol, we will fill the alias list buffer.
|
||||
if (split_line.size() > 2 && !split_line[2].starts_with('#')) {
|
||||
|
||||
for (size_t i = 2; i < split_line.size(); i++) {
|
||||
if (split_line[i].starts_with('#'))
|
||||
break;
|
||||
auto alias = split_line[i].to_byte_buffer();
|
||||
alias.append("\0", sizeof(char));
|
||||
__getproto_alias_list_buffer.append(alias);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
78
Userland/Libraries/LibC/netdb.h
Normal file
78
Userland/Libraries/LibC/netdb.h
Normal file
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
struct hostent {
|
||||
char* h_name;
|
||||
char** h_aliases;
|
||||
int h_addrtype;
|
||||
int h_length;
|
||||
char** h_addr_list;
|
||||
#define h_addr h_addr_list[0]
|
||||
};
|
||||
|
||||
struct hostent* gethostbyname(const char*);
|
||||
struct hostent* gethostbyaddr(const void* addr, socklen_t len, int type);
|
||||
|
||||
struct servent {
|
||||
char* s_name;
|
||||
char** s_aliases;
|
||||
int s_port;
|
||||
char* s_proto;
|
||||
};
|
||||
|
||||
struct servent* getservent();
|
||||
struct servent* getservbyname(const char* name, const char* protocol);
|
||||
struct servent* getservbyport(int port, const char* protocol);
|
||||
void setservent(int stay_open);
|
||||
void endservent();
|
||||
|
||||
struct protoent {
|
||||
char* p_name;
|
||||
char** p_aliases;
|
||||
int p_proto;
|
||||
};
|
||||
|
||||
void endprotoent();
|
||||
struct protoent* getprotobyname(const char* name);
|
||||
struct protoent* getprotobynumber(int proto);
|
||||
struct protoent* getprotoent();
|
||||
void setprotoent(int stay_open);
|
||||
|
||||
extern int h_errno;
|
||||
|
||||
#define HOST_NOT_FOUND 101
|
||||
#define NO_DATA 102
|
||||
#define NO_RECOVERY 103
|
||||
#define TRY_AGAIN 104
|
||||
|
||||
__END_DECLS
|
74
Userland/Libraries/LibC/netinet/in.h
Normal file
74
Userland/Libraries/LibC/netinet/in.h
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <bits/stdint.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
typedef uint32_t in_addr_t;
|
||||
in_addr_t inet_addr(const char*);
|
||||
|
||||
#define INADDR_ANY ((in_addr_t)0)
|
||||
#define INADDR_NONE ((in_addr_t)-1)
|
||||
#define INADDR_LOOPBACK 0x7f000001
|
||||
|
||||
#define IN_LOOPBACKNET 127
|
||||
|
||||
#define IP_TTL 2
|
||||
|
||||
#define IPPORT_RESERVED 1024
|
||||
#define IPPORT_USERRESERVED 5000
|
||||
|
||||
typedef uint16_t in_port_t;
|
||||
|
||||
struct in_addr {
|
||||
uint32_t s_addr;
|
||||
};
|
||||
|
||||
struct sockaddr_in {
|
||||
sa_family_t sin_family;
|
||||
in_port_t sin_port;
|
||||
struct in_addr sin_addr;
|
||||
char sin_zero[8];
|
||||
};
|
||||
|
||||
struct in6_addr {
|
||||
uint8_t s6_addr[16];
|
||||
};
|
||||
|
||||
struct sockaddr_in6 {
|
||||
sa_family_t sin6_family; // AF_INET6.
|
||||
in_port_t sin6_port; // Port number.
|
||||
uint32_t sin6_flowinfo; // IPv6 traffic class and flow information.
|
||||
struct in6_addr sin6_addr; // IPv6 address.
|
||||
uint32_t sin6_scope_id; // Set of interfaces for a scop
|
||||
};
|
||||
|
||||
__END_DECLS
|
29
Userland/Libraries/LibC/netinet/ip.h
Normal file
29
Userland/Libraries/LibC/netinet/ip.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "in.h"
|
47
Userland/Libraries/LibC/netinet/ip_icmp.h
Normal file
47
Userland/Libraries/LibC/netinet/ip_icmp.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <bits/stdint.h>
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
struct icmphdr {
|
||||
uint8_t type;
|
||||
uint8_t code;
|
||||
uint16_t checksum;
|
||||
union {
|
||||
struct {
|
||||
uint16_t id;
|
||||
uint16_t sequence;
|
||||
} echo;
|
||||
uint32_t gateway;
|
||||
} un;
|
||||
};
|
||||
|
||||
__END_DECLS
|
29
Userland/Libraries/LibC/netinet/tcp.h
Normal file
29
Userland/Libraries/LibC/netinet/tcp.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (c) 2020, the SerenityOS developers.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define TCP_NODELAY 10
|
30
Userland/Libraries/LibC/paths.h
Normal file
30
Userland/Libraries/LibC/paths.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright (c) 2020, The SerenityOS developers.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// FIXME: This is just a default value to satisfy OpenSSH, feel free to change it.
|
||||
#define _PATH_MAILDIR "/var/mail"
|
51
Userland/Libraries/LibC/poll.cpp
Normal file
51
Userland/Libraries/LibC/poll.cpp
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <Kernel/API/Syscall.h>
|
||||
#include <errno.h>
|
||||
#include <poll.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
int poll(pollfd* fds, nfds_t nfds, int timeout_ms)
|
||||
{
|
||||
timespec timeout;
|
||||
timespec* timeout_ts = &timeout;
|
||||
if (timeout_ms < 0)
|
||||
timeout_ts = nullptr;
|
||||
else
|
||||
timeout = { timeout_ms / 1000, (timeout_ms % 1000) * 1'000'000 };
|
||||
return ppoll(fds, nfds, timeout_ts, nullptr);
|
||||
}
|
||||
|
||||
int ppoll(pollfd* fds, nfds_t nfds, const timespec* timeout, const sigset_t* sigmask)
|
||||
{
|
||||
Syscall::SC_poll_params params { fds, nfds, timeout, sigmask };
|
||||
int rc = syscall(SC_poll, ¶ms);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
}
|
53
Userland/Libraries/LibC/poll.h
Normal file
53
Userland/Libraries/LibC/poll.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <signal.h>
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
#define POLLIN (1u << 0)
|
||||
#define POLLPRI (1u << 1)
|
||||
#define POLLOUT (1u << 2)
|
||||
#define POLLERR (1u << 3)
|
||||
#define POLLHUP (1u << 4)
|
||||
#define POLLNVAL (1u << 5)
|
||||
#define POLLRDHUP (1u << 13)
|
||||
|
||||
struct pollfd {
|
||||
int fd;
|
||||
short events;
|
||||
short revents;
|
||||
};
|
||||
|
||||
typedef unsigned nfds_t;
|
||||
|
||||
int poll(struct pollfd* fds, nfds_t nfds, int timeout);
|
||||
int ppoll(struct pollfd* fds, nfds_t nfds, const struct timespec* timeout, const sigset_t* sigmask);
|
||||
|
||||
__END_DECLS
|
189
Userland/Libraries/LibC/pwd.cpp
Normal file
189
Userland/Libraries/LibC/pwd.cpp
Normal file
|
@ -0,0 +1,189 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <AK/String.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <errno_numbers.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
static FILE* s_stream = nullptr;
|
||||
static unsigned s_line_number = 0;
|
||||
static struct passwd s_passwd_entry;
|
||||
|
||||
static String s_name;
|
||||
static String s_passwd;
|
||||
static String s_gecos;
|
||||
static String s_dir;
|
||||
static String s_shell;
|
||||
|
||||
void setpwent()
|
||||
{
|
||||
s_line_number = 0;
|
||||
if (s_stream) {
|
||||
rewind(s_stream);
|
||||
} else {
|
||||
s_stream = fopen("/etc/passwd", "r");
|
||||
if (!s_stream) {
|
||||
perror("open /etc/passwd");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void endpwent()
|
||||
{
|
||||
s_line_number = 0;
|
||||
if (s_stream) {
|
||||
fclose(s_stream);
|
||||
s_stream = nullptr;
|
||||
}
|
||||
|
||||
memset(&s_passwd_entry, 0, sizeof(s_passwd_entry));
|
||||
|
||||
s_name = {};
|
||||
s_passwd = {};
|
||||
s_gecos = {};
|
||||
s_dir = {};
|
||||
s_shell = {};
|
||||
}
|
||||
|
||||
struct passwd* getpwuid(uid_t uid)
|
||||
{
|
||||
setpwent();
|
||||
while (auto* pw = getpwent()) {
|
||||
if (pw->pw_uid == uid)
|
||||
return pw;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
struct passwd* getpwnam(const char* name)
|
||||
{
|
||||
setpwent();
|
||||
while (auto* pw = getpwent()) {
|
||||
if (!strcmp(pw->pw_name, name))
|
||||
return pw;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static bool parse_pwddb_entry(const String& line)
|
||||
{
|
||||
auto parts = line.split_view(':', true);
|
||||
if (parts.size() != 7) {
|
||||
fprintf(stderr, "getpwent(): Malformed entry on line %u\n", s_line_number);
|
||||
return false;
|
||||
}
|
||||
|
||||
s_name = parts[0];
|
||||
s_passwd = parts[1];
|
||||
auto& uid_string = parts[2];
|
||||
auto& gid_string = parts[3];
|
||||
s_gecos = parts[4];
|
||||
s_dir = parts[5];
|
||||
s_shell = parts[6];
|
||||
|
||||
auto uid = uid_string.to_uint();
|
||||
if (!uid.has_value()) {
|
||||
fprintf(stderr, "getpwent(): Malformed UID on line %u\n", s_line_number);
|
||||
return false;
|
||||
}
|
||||
auto gid = gid_string.to_uint();
|
||||
if (!gid.has_value()) {
|
||||
fprintf(stderr, "getpwent(): Malformed GID on line %u\n", s_line_number);
|
||||
return false;
|
||||
}
|
||||
|
||||
s_passwd_entry.pw_name = const_cast<char*>(s_name.characters());
|
||||
s_passwd_entry.pw_passwd = const_cast<char*>(s_passwd.characters());
|
||||
s_passwd_entry.pw_uid = uid.value();
|
||||
s_passwd_entry.pw_gid = gid.value();
|
||||
s_passwd_entry.pw_gecos = const_cast<char*>(s_gecos.characters());
|
||||
s_passwd_entry.pw_dir = const_cast<char*>(s_dir.characters());
|
||||
s_passwd_entry.pw_shell = const_cast<char*>(s_shell.characters());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
struct passwd* getpwent()
|
||||
{
|
||||
if (!s_stream)
|
||||
setpwent();
|
||||
|
||||
while (true) {
|
||||
if (!s_stream || feof(s_stream))
|
||||
return nullptr;
|
||||
|
||||
if (ferror(s_stream)) {
|
||||
fprintf(stderr, "getpwent(): Read error: %s\n", strerror(ferror(s_stream)));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
char buffer[1024];
|
||||
++s_line_number;
|
||||
char* s = fgets(buffer, sizeof(buffer), s_stream);
|
||||
|
||||
// Silently tolerate an empty line at the end.
|
||||
if ((!s || !s[0]) && feof(s_stream))
|
||||
return nullptr;
|
||||
|
||||
String line(s, Chomp);
|
||||
if (parse_pwddb_entry(line))
|
||||
return &s_passwd_entry;
|
||||
// Otherwise, proceed to the next line.
|
||||
}
|
||||
}
|
||||
|
||||
int putpwent(const struct passwd* p, FILE* stream)
|
||||
{
|
||||
if (!p || !stream || !p->pw_passwd || !p->pw_name || !p->pw_dir || !p->pw_gecos || !p->pw_shell) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
auto is_valid_field = [](const char* str) {
|
||||
return str && !strpbrk(str, ":\n");
|
||||
};
|
||||
|
||||
if (!is_valid_field(p->pw_name) || !is_valid_field(p->pw_dir) || !is_valid_field(p->pw_gecos) || !is_valid_field(p->pw_shell)) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int nwritten = fprintf(stream, "%s:%s:%u:%u:%s,,,:%s:%s\n", p->pw_name, p->pw_passwd, p->pw_uid, p->pw_gid, p->pw_gecos, p->pw_dir, p->pw_shell);
|
||||
if (!nwritten || nwritten < 0) {
|
||||
errno = ferror(stream);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
52
Userland/Libraries/LibC/pwd.h
Normal file
52
Userland/Libraries/LibC/pwd.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <bits/FILE.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
struct passwd {
|
||||
char* pw_name;
|
||||
char* pw_passwd;
|
||||
uid_t pw_uid;
|
||||
gid_t pw_gid;
|
||||
char* pw_gecos;
|
||||
char* pw_dir;
|
||||
char* pw_shell;
|
||||
};
|
||||
|
||||
struct passwd* getpwent();
|
||||
void setpwent();
|
||||
void endpwent();
|
||||
struct passwd* getpwnam(const char* name);
|
||||
struct passwd* getpwuid(uid_t);
|
||||
int putpwent(const struct passwd* p, FILE* stream);
|
||||
|
||||
__END_DECLS
|
102
Userland/Libraries/LibC/qsort.cpp
Normal file
102
Userland/Libraries/LibC/qsort.cpp
Normal file
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <AK/Assertions.h>
|
||||
#include <AK/QuickSort.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
class SizedObject {
|
||||
public:
|
||||
SizedObject() = delete;
|
||||
SizedObject(void* data, size_t size)
|
||||
: m_data(data)
|
||||
, m_size(size)
|
||||
{
|
||||
}
|
||||
void* data() const { return m_data; }
|
||||
size_t size() const { return m_size; }
|
||||
|
||||
private:
|
||||
void* m_data;
|
||||
size_t m_size;
|
||||
};
|
||||
|
||||
namespace AK {
|
||||
|
||||
template<>
|
||||
inline void swap(const SizedObject& a, const SizedObject& b)
|
||||
{
|
||||
ASSERT(a.size() == b.size());
|
||||
const size_t size = a.size();
|
||||
const auto a_data = reinterpret_cast<char*>(a.data());
|
||||
const auto b_data = reinterpret_cast<char*>(b.data());
|
||||
for (auto i = 0u; i < size; ++i) {
|
||||
swap(a_data[i], b_data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class SizedObjectSlice {
|
||||
public:
|
||||
SizedObjectSlice() = delete;
|
||||
SizedObjectSlice(void* data, size_t element_size)
|
||||
: m_data(data)
|
||||
, m_element_size(element_size)
|
||||
{
|
||||
}
|
||||
const SizedObject operator[](size_t index)
|
||||
{
|
||||
return { static_cast<char*>(m_data) + index * m_element_size, m_element_size };
|
||||
}
|
||||
|
||||
private:
|
||||
void* m_data;
|
||||
size_t m_element_size;
|
||||
};
|
||||
|
||||
void qsort(void* bot, size_t nmemb, size_t size, int (*compar)(const void*, const void*))
|
||||
{
|
||||
if (nmemb <= 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
SizedObjectSlice slice { bot, size };
|
||||
|
||||
AK::dual_pivot_quick_sort(slice, 0, nmemb - 1, [=](const SizedObject& a, const SizedObject& b) { return compar(a.data(), b.data()) < 0; });
|
||||
}
|
||||
|
||||
void qsort_r(void* bot, size_t nmemb, size_t size, int (*compar)(const void*, const void*, void*), void* arg)
|
||||
{
|
||||
if (nmemb <= 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
SizedObjectSlice slice { bot, size };
|
||||
|
||||
AK::dual_pivot_quick_sort(slice, 0, nmemb - 1, [=](const SizedObject& a, const SizedObject& b) { return compar(a.data(), b.data(), arg) < 0; });
|
||||
}
|
125
Userland/Libraries/LibC/regex.h
Normal file
125
Userland/Libraries/LibC/regex.h
Normal file
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Emanuel Sprung <emanuel.sprung@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
typedef ssize_t regoff_t;
|
||||
|
||||
struct regex_t {
|
||||
void* __data;
|
||||
};
|
||||
|
||||
enum __Regex_Error {
|
||||
__Regex_NoError,
|
||||
__Regex_InvalidPattern, // Invalid regular expression.
|
||||
__Regex_InvalidCollationElement, // Invalid collating element referenced.
|
||||
__Regex_InvalidCharacterClass, // Invalid character class type referenced.
|
||||
__Regex_InvalidTrailingEscape, // Trailing \ in pattern.
|
||||
__Regex_InvalidNumber, // Number in \digit invalid or in error.
|
||||
__Regex_MismatchingBracket, // [ ] imbalance.
|
||||
__Regex_MismatchingParen, // ( ) imbalance.
|
||||
__Regex_MismatchingBrace, // { } imbalance.
|
||||
__Regex_InvalidBraceContent, // Content of {} invalid: not a number, number too large, more than two numbers, first larger than second.
|
||||
__Regex_InvalidBracketContent, // Content of [] invalid.
|
||||
__Regex_InvalidRange, // Invalid endpoint in range expression.
|
||||
__Regex_InvalidRepetitionMarker, // ?, * or + not preceded by valid regular expression.
|
||||
__Regex_ReachedMaxRecursion, // MaximumRecursion has been reached.
|
||||
__Regex_EmptySubExpression, // Sub expression has empty content.
|
||||
__Regex_InvalidCaptureGroup, // Content of capture group is invalid.
|
||||
__Regex_InvalidNameForCaptureGroup, // Name of capture group is invalid.
|
||||
};
|
||||
|
||||
enum ReError {
|
||||
REG_NOERR = __Regex_NoError,
|
||||
REG_BADPAT = __Regex_InvalidPattern, // Invalid regular expression.
|
||||
REG_ECOLLATE = __Regex_InvalidCollationElement, // Invalid collating element referenced.
|
||||
REG_ECTYPE = __Regex_InvalidCharacterClass, // Invalid character class type referenced.
|
||||
REG_EESCAPE = __Regex_InvalidTrailingEscape, // Trailing \ in pattern.
|
||||
REG_ESUBREG = __Regex_InvalidNumber, // Number in \digit invalid or in error.
|
||||
REG_EBRACK = __Regex_MismatchingBracket, // [ ] imbalance.
|
||||
REG_EPAREN = __Regex_MismatchingParen, // \( \) or ( ) imbalance.
|
||||
REG_EBRACE = __Regex_MismatchingBrace, // \{ \} imbalance.
|
||||
REG_BADBR = __Regex_InvalidBraceContent, // Content of \{ \} invalid: not a number, number too large, more than two numbers, first larger than second.
|
||||
REG_ERANGE = __Regex_InvalidRange, // Invalid endpoint in range expression.
|
||||
REG_BADRPT = __Regex_InvalidRepetitionMarker, // ?, * or + not preceded by valid regular expression.
|
||||
REG_EMPTY_EXPR = __Regex_EmptySubExpression, // Empty expression
|
||||
REG_ENOSYS, // The implementation does not support the function.
|
||||
REG_ESPACE, // Out of memory.
|
||||
REG_NOMATCH, // regexec() failed to match.
|
||||
};
|
||||
|
||||
struct regmatch_t {
|
||||
regoff_t rm_so; // byte offset from start of string to start of substring
|
||||
regoff_t rm_eo; // byte offset from start of string of the first character after the end of substring
|
||||
regoff_t rm_cnt; // number of matches
|
||||
};
|
||||
|
||||
enum __RegexAllFlags {
|
||||
__Regex_Global = 1, // All matches (don't return after first match)
|
||||
__Regex_Insensitive = __Regex_Global << 1, // Case insensitive match (ignores case of [a-zA-Z])
|
||||
__Regex_Ungreedy = __Regex_Global << 2, // The match becomes lazy by default. Now a ? following a quantifier makes it greedy
|
||||
__Regex_Unicode = __Regex_Global << 3, // Enable all unicode features and interpret all unicode escape sequences as such
|
||||
__Regex_Extended = __Regex_Global << 4, // Ignore whitespaces. Spaces and text after a # in the pattern are ignored
|
||||
__Regex_Extra = __Regex_Global << 5, // Disallow meaningless escapes. A \ followed by a letter with no special meaning is faulted
|
||||
__Regex_MatchNotBeginOfLine = __Regex_Global << 6, // Pattern is not forced to ^ -> search in whole string!
|
||||
__Regex_MatchNotEndOfLine = __Regex_Global << 7, // Don't Force the dollar sign, $, to always match end of the string, instead of end of the line. This option is ignored if the Multiline-flag is set
|
||||
__Regex_SkipSubExprResults = __Regex_Global << 8, // Do not return sub expressions in the result
|
||||
__Regex_StringCopyMatches = __Regex_Global << 9, // Do explicitly copy results into new allocated string instead of StringView to original string.
|
||||
__Regex_SingleLine = __Regex_Global << 10, // Dot matches newline characters
|
||||
__Regex_Sticky = __Regex_Global << 11, // Force the pattern to only match consecutive matches from where the previous match ended.
|
||||
__Regex_Multiline = __Regex_Global << 12, // Handle newline characters. Match each line, one by one.
|
||||
__Regex_SkipTrimEmptyMatches = __Regex_Global << 13, // Do not remove empty capture group results.
|
||||
__Regex_Internal_Stateful = __Regex_Global << 14, // Internal flag; enables stateful matches.
|
||||
__Regex_Last = __Regex_SkipTrimEmptyMatches
|
||||
};
|
||||
|
||||
// clang-format off
|
||||
// Values for the cflags parameter to the regcomp() function:
|
||||
#define REG_EXTENDED __Regex_Extended // Use Extended Regular Expressions.
|
||||
#define REG_ICASE __Regex_Insensitive // Ignore case in match.
|
||||
#define REG_NOSUB __Regex_SkipSubExprResults // Report only success or fail in regexec().
|
||||
#define REG_GLOBAL __Regex_Global // Don't stop searching for more match
|
||||
#define REG_NEWLINE (__Regex_Multiline | REG_GLOBAL) // Change the handling of newline.
|
||||
|
||||
// Values for the eflags parameter to the regexec() function:
|
||||
#define REG_NOTBOL __Regex_MatchNotBeginOfLine // The circumflex character (^), when taken as a special character, will not match the beginning of string.
|
||||
#define REG_NOTEOL __Regex_MatchNotEndOfLine // The dollar sign ($), when taken as a special character, will not match the end of string.
|
||||
|
||||
//static_assert (sizeof(FlagsUnderlyingType) * 8 >= regex::POSIXFlags::Last << 1), "flags type too small")
|
||||
#define REG_SEARCH __Regex_Last << 1
|
||||
// clang-format on
|
||||
|
||||
int regcomp(regex_t*, const char*, int);
|
||||
int regexec(const regex_t*, const char*, size_t, regmatch_t[], int);
|
||||
size_t regerror(int, const regex_t*, char*, size_t);
|
||||
void regfree(regex_t*);
|
||||
|
||||
__END_DECLS
|
227
Userland/Libraries/LibC/scanf.cpp
Normal file
227
Userland/Libraries/LibC/scanf.cpp
Normal file
|
@ -0,0 +1,227 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2002 Opsycon AB (www.opsycon.se)
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Opsycon AB.
|
||||
* 4. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include <AK/Assertions.h>
|
||||
#include <ctype.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
static const char* determine_base(const char* p, int& base)
|
||||
{
|
||||
if (p[0] == '0') {
|
||||
switch (p[1]) {
|
||||
case 'x':
|
||||
base = 16;
|
||||
break;
|
||||
case 't':
|
||||
case 'n':
|
||||
base = 10;
|
||||
break;
|
||||
case 'o':
|
||||
base = 8;
|
||||
break;
|
||||
default:
|
||||
base = 10;
|
||||
return p;
|
||||
}
|
||||
return p + 2;
|
||||
}
|
||||
base = 10;
|
||||
return p;
|
||||
}
|
||||
|
||||
static int _atob(unsigned long* vp, const char* p, int base)
|
||||
{
|
||||
unsigned long value, v1, v2;
|
||||
const char* q;
|
||||
char tmp[20];
|
||||
int digit;
|
||||
|
||||
if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) {
|
||||
base = 16;
|
||||
p += 2;
|
||||
}
|
||||
|
||||
if (base == 16 && (q = strchr(p, '.')) != 0) {
|
||||
if (q - p > (ssize_t)sizeof(tmp) - 1)
|
||||
return 0;
|
||||
memcpy(tmp, p, q - p);
|
||||
tmp[q - p] = '\0';
|
||||
|
||||
if (!_atob(&v1, tmp, 16))
|
||||
return 0;
|
||||
++q;
|
||||
if (strchr(q, '.'))
|
||||
return 0;
|
||||
if (!_atob(&v2, q, 16))
|
||||
return 0;
|
||||
*vp = (v1 << 16) + v2;
|
||||
return 1;
|
||||
}
|
||||
|
||||
value = *vp = 0;
|
||||
for (; *p; p++) {
|
||||
if (*p >= '0' && *p <= '9')
|
||||
digit = *p - '0';
|
||||
else if (*p >= 'a' && *p <= 'f')
|
||||
digit = *p - 'a' + 10;
|
||||
else if (*p >= 'A' && *p <= 'F')
|
||||
digit = *p - 'A' + 10;
|
||||
else
|
||||
return 0;
|
||||
|
||||
if (digit >= base)
|
||||
return 0;
|
||||
value *= base;
|
||||
value += digit;
|
||||
}
|
||||
*vp = value;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int atob(unsigned int* vp, const char* p, int base)
|
||||
{
|
||||
unsigned long v;
|
||||
|
||||
if (base == 0)
|
||||
p = determine_base(p, base);
|
||||
if (_atob(&v, p, base)) {
|
||||
*vp = v;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define ISSPACE " \t\n\r\f\v"
|
||||
|
||||
int vsscanf(const char* buf, const char* s, va_list ap)
|
||||
{
|
||||
int base = 10;
|
||||
char* t;
|
||||
char tmp[BUFSIZ];
|
||||
bool noassign = false;
|
||||
int count = 0;
|
||||
int width = 0;
|
||||
|
||||
// FIXME: This doesn't work quite right. For example, it fails to match 'SSH-2.0-OpenSSH_8.2p1 Ubuntu-4ubuntu0.1\r\n'
|
||||
// with 'SSH-%d.%d-%[^\n]\n'
|
||||
|
||||
while (*s && *buf) {
|
||||
while (isspace(*s))
|
||||
s++;
|
||||
if (*s == '%') {
|
||||
s++;
|
||||
for (; *s; s++) {
|
||||
if (strchr("dibouxcsefg%", *s))
|
||||
break;
|
||||
if (*s == '*')
|
||||
noassign = true;
|
||||
else if (*s >= '1' && *s <= '9') {
|
||||
const char* tc;
|
||||
for (tc = s; isdigit(*s); s++)
|
||||
;
|
||||
ASSERT((ssize_t)sizeof(tmp) >= s - tc + 1);
|
||||
memcpy(tmp, tc, s - tc);
|
||||
tmp[s - tc] = '\0';
|
||||
atob((uint32_t*)&width, tmp, 10);
|
||||
s--;
|
||||
}
|
||||
}
|
||||
if (*s == 's') {
|
||||
while (isspace(*buf))
|
||||
buf++;
|
||||
if (!width)
|
||||
width = strcspn(buf, ISSPACE);
|
||||
if (!noassign) {
|
||||
// In this case, we have no way to ensure the user buffer is not overflown :(
|
||||
memcpy(t = va_arg(ap, char*), buf, width);
|
||||
t[width] = '\0';
|
||||
}
|
||||
buf += width;
|
||||
} else if (*s == 'c') {
|
||||
if (!width)
|
||||
width = 1;
|
||||
if (!noassign) {
|
||||
memcpy(t = va_arg(ap, char*), buf, width);
|
||||
// No null terminator!
|
||||
}
|
||||
buf += width;
|
||||
} else if (strchr("dobxu", *s)) {
|
||||
while (isspace(*buf))
|
||||
buf++;
|
||||
if (*s == 'd' || *s == 'u')
|
||||
base = 10;
|
||||
else if (*s == 'x')
|
||||
base = 16;
|
||||
else if (*s == 'o')
|
||||
base = 8;
|
||||
else if (*s == 'b')
|
||||
base = 2;
|
||||
if (!width) {
|
||||
if (isspace(*(s + 1)) || *(s + 1) == 0) {
|
||||
width = strcspn(buf, ISSPACE);
|
||||
} else {
|
||||
auto* p = strchr(buf, *(s + 1));
|
||||
if (p)
|
||||
width = p - buf;
|
||||
else {
|
||||
noassign = true;
|
||||
width = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
memcpy(tmp, buf, width);
|
||||
tmp[width] = '\0';
|
||||
buf += width;
|
||||
if (!noassign) {
|
||||
if (!atob(va_arg(ap, uint32_t*), tmp, base))
|
||||
noassign = true;
|
||||
}
|
||||
}
|
||||
if (!noassign)
|
||||
++count;
|
||||
width = 0;
|
||||
noassign = false;
|
||||
++s;
|
||||
} else {
|
||||
while (isspace(*buf))
|
||||
buf++;
|
||||
if (*s != *buf)
|
||||
break;
|
||||
else {
|
||||
++s;
|
||||
++buf;
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
60
Userland/Libraries/LibC/sched.cpp
Normal file
60
Userland/Libraries/LibC/sched.cpp
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <Kernel/API/Syscall.h>
|
||||
#include <errno.h>
|
||||
#include <sched.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
int sched_yield()
|
||||
{
|
||||
int rc = syscall(SC_yield);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
|
||||
int sched_get_priority_min([[maybe_unused]] int policy)
|
||||
{
|
||||
return 0; // Idle
|
||||
}
|
||||
|
||||
int sched_get_priority_max([[maybe_unused]] int policy)
|
||||
{
|
||||
return 3; // High
|
||||
}
|
||||
|
||||
int sched_setparam(pid_t pid, const struct sched_param* param)
|
||||
{
|
||||
int rc = syscall(SC_sched_setparam, pid, param);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
|
||||
int sched_getparam(pid_t pid, struct sched_param* param)
|
||||
{
|
||||
int rc = syscall(SC_sched_getparam, pid, param);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
}
|
50
Userland/Libraries/LibC/sched.h
Normal file
50
Userland/Libraries/LibC/sched.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
int sched_yield();
|
||||
|
||||
struct sched_param {
|
||||
int sched_priority;
|
||||
};
|
||||
|
||||
#define SCHED_FIFO 0
|
||||
#define SCHED_RR 1
|
||||
#define SCHED_OTHER 2
|
||||
#define SCHED_BATCH 3
|
||||
|
||||
int sched_get_priority_min(int policy);
|
||||
int sched_get_priority_max(int policy);
|
||||
int sched_setparam(pid_t pid, const struct sched_param* param);
|
||||
int sched_getparam(pid_t pid, struct sched_param* param);
|
||||
|
||||
__END_DECLS
|
139
Userland/Libraries/LibC/serenity.cpp
Normal file
139
Userland/Libraries/LibC/serenity.cpp
Normal file
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <Kernel/API/Syscall.h>
|
||||
#include <errno.h>
|
||||
#include <serenity.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
int disown(pid_t pid)
|
||||
{
|
||||
int rc = syscall(SC_disown, pid);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
|
||||
int module_load(const char* path, size_t path_length)
|
||||
{
|
||||
int rc = syscall(SC_module_load, path, path_length);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
|
||||
int module_unload(const char* name, size_t name_length)
|
||||
{
|
||||
int rc = syscall(SC_module_unload, name, name_length);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
|
||||
int profiling_enable(pid_t pid)
|
||||
{
|
||||
int rc = syscall(SC_profiling_enable, pid);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
|
||||
int profiling_disable(pid_t pid)
|
||||
{
|
||||
int rc = syscall(SC_profiling_disable, pid);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
|
||||
int set_thread_boost(pid_t tid, int amount)
|
||||
{
|
||||
int rc = syscall(SC_set_thread_boost, tid, amount);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
|
||||
int set_process_boost(pid_t tid, int amount)
|
||||
{
|
||||
int rc = syscall(SC_set_process_boost, tid, amount);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
|
||||
int futex(int32_t* userspace_address, int futex_op, int32_t value, const struct timespec* timeout)
|
||||
{
|
||||
Syscall::SC_futex_params params { userspace_address, futex_op, value, timeout };
|
||||
int rc = syscall(SC_futex, ¶ms);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
|
||||
int purge(int mode)
|
||||
{
|
||||
int rc = syscall(SC_purge, mode);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
|
||||
int perf_event(int type, uintptr_t arg1, FlatPtr arg2)
|
||||
{
|
||||
int rc = syscall(SC_perf_event, type, arg1, arg2);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
|
||||
void* shbuf_get(int shbuf_id, size_t* size)
|
||||
{
|
||||
ssize_t rc = syscall(SC_shbuf_get, shbuf_id, size);
|
||||
if (rc < 0 && -rc < EMAXERRNO) {
|
||||
errno = -rc;
|
||||
return (void*)-1;
|
||||
}
|
||||
return (void*)rc;
|
||||
}
|
||||
|
||||
int shbuf_release(int shbuf_id)
|
||||
{
|
||||
int rc = syscall(SC_shbuf_release, shbuf_id);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
|
||||
int shbuf_seal(int shbuf_id)
|
||||
{
|
||||
int rc = syscall(SC_shbuf_seal, shbuf_id);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
|
||||
int shbuf_create(int size, void** buffer)
|
||||
{
|
||||
int rc = syscall(SC_shbuf_create, size, buffer);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
|
||||
int shbuf_allow_pid(int shbuf_id, pid_t peer_pid)
|
||||
{
|
||||
int rc = syscall(SC_shbuf_allow_pid, shbuf_id, peer_pid);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
|
||||
int shbuf_allow_all(int shbuf_id)
|
||||
{
|
||||
int rc = syscall(SC_shbuf_allow_all, shbuf_id);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
|
||||
int get_stack_bounds(uintptr_t* user_stack_base, size_t* user_stack_size)
|
||||
{
|
||||
int rc = syscall(SC_get_stack_bounds, user_stack_base, user_stack_size);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
}
|
99
Userland/Libraries/LibC/serenity.h
Normal file
99
Userland/Libraries/LibC/serenity.h
Normal file
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
int disown(pid_t);
|
||||
|
||||
int shbuf_create(int, void** buffer);
|
||||
int shbuf_allow_pid(int, pid_t peer_pid);
|
||||
int shbuf_allow_all(int);
|
||||
void* shbuf_get(int shbuf_id, size_t* size);
|
||||
int shbuf_release(int shbuf_id);
|
||||
int shbuf_seal(int shbuf_id);
|
||||
|
||||
int module_load(const char* path, size_t path_length);
|
||||
int module_unload(const char* name, size_t name_length);
|
||||
|
||||
int profiling_enable(pid_t);
|
||||
int profiling_disable(pid_t);
|
||||
|
||||
#define THREAD_PRIORITY_MIN 1
|
||||
#define THREAD_PRIORITY_LOW 10
|
||||
#define THREAD_PRIORITY_NORMAL 30
|
||||
#define THREAD_PRIORITY_HIGH 50
|
||||
#define THREAD_PRIORITY_MAX 99
|
||||
|
||||
int set_thread_boost(pid_t tid, int amount);
|
||||
int set_process_boost(pid_t, int amount);
|
||||
|
||||
#define FUTEX_WAIT 1
|
||||
#define FUTEX_WAKE 2
|
||||
|
||||
int futex(int32_t* userspace_address, int futex_op, int32_t value, const struct timespec* timeout);
|
||||
|
||||
#define PURGE_ALL_VOLATILE 0x1
|
||||
#define PURGE_ALL_CLEAN_INODE 0x2
|
||||
|
||||
int purge(int mode);
|
||||
|
||||
#define PERF_EVENT_SAMPLE 0
|
||||
#define PERF_EVENT_MALLOC 1
|
||||
#define PERF_EVENT_FREE 2
|
||||
|
||||
int perf_event(int type, uintptr_t arg1, uintptr_t arg2);
|
||||
|
||||
int get_stack_bounds(uintptr_t* user_stack_base, size_t* user_stack_size);
|
||||
|
||||
#ifdef __i386__
|
||||
ALWAYS_INLINE void send_secret_data_to_userspace_emulator(uintptr_t data1, uintptr_t data2, uintptr_t data3)
|
||||
{
|
||||
asm volatile(
|
||||
".byte 0xd6\n"
|
||||
".byte 0xd6\n" ::
|
||||
: "eax");
|
||||
asm volatile(
|
||||
"push %%eax\n"
|
||||
"push %%ecx\n"
|
||||
"push %%edx\n"
|
||||
"pop %%edx\n"
|
||||
"pop %%ecx\n"
|
||||
"pop %%eax\n" ::"a"(data1),
|
||||
"c"(data2), "d"(data3)
|
||||
: "memory");
|
||||
}
|
||||
#elif __x86_64__
|
||||
ALWAYS_INLINE void send_secret_data_to_userspace_emulator(uintptr_t, uintptr_t, uintptr_t)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
__END_DECLS
|
57
Userland/Libraries/LibC/setjmp.S
Normal file
57
Userland/Libraries/LibC/setjmp.S
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
.global setjmp
|
||||
setjmp:
|
||||
mov 4(%esp), %eax
|
||||
mov %ebx, 0(%eax)
|
||||
mov %esi, 4(%eax)
|
||||
mov %edi, 8(%eax)
|
||||
mov %ebp, 12(%eax)
|
||||
lea 4(%esp), %ecx
|
||||
mov %ecx, 16(%eax)
|
||||
mov (%esp), %ecx
|
||||
mov %ecx, 20(%eax)
|
||||
xor %eax, %eax
|
||||
ret
|
||||
|
||||
.global longjmp
|
||||
longjmp:
|
||||
mov 4(%esp), %edx
|
||||
mov 8(%esp), %eax
|
||||
mov 0(%edx), %ebx
|
||||
mov 4(%edx), %esi
|
||||
mov 8(%edx), %edi
|
||||
mov 12(%edx), %ebp
|
||||
mov 16(%edx), %ecx
|
||||
mov %ecx, %esp
|
||||
mov 20(%edx), %ecx
|
||||
test %eax, %eax
|
||||
jnz .nonzero
|
||||
mov 1, %eax
|
||||
.nonzero:
|
||||
jmp *%ecx
|
||||
|
52
Userland/Libraries/LibC/setjmp.h
Normal file
52
Userland/Libraries/LibC/setjmp.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <bits/stdint.h>
|
||||
#include <signal.h>
|
||||
#include <stdbool.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
struct __jmp_buf {
|
||||
uint32_t regs[6];
|
||||
bool did_save_signal_mask;
|
||||
sigset_t saved_signal_mask;
|
||||
};
|
||||
|
||||
typedef struct __jmp_buf jmp_buf[1];
|
||||
typedef struct __jmp_buf sigjmp_buf[1];
|
||||
|
||||
int setjmp(jmp_buf);
|
||||
void longjmp(jmp_buf, int val);
|
||||
|
||||
int sigsetjmp(sigjmp_buf, int savesigs);
|
||||
void siglongjmp(sigjmp_buf, int val);
|
||||
|
||||
__END_DECLS
|
248
Userland/Libraries/LibC/signal.cpp
Normal file
248
Userland/Libraries/LibC/signal.cpp
Normal file
|
@ -0,0 +1,248 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <Kernel/API/Syscall.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
int kill(pid_t pid, int sig)
|
||||
{
|
||||
int rc = syscall(SC_kill, pid, sig);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
|
||||
int killpg(int pgrp, int sig)
|
||||
{
|
||||
int rc = syscall(SC_killpg, pgrp, sig);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
|
||||
int raise(int sig)
|
||||
{
|
||||
// FIXME: Support multi-threaded programs.
|
||||
return kill(getpid(), sig);
|
||||
}
|
||||
|
||||
sighandler_t signal(int signum, sighandler_t handler)
|
||||
{
|
||||
struct sigaction new_act;
|
||||
struct sigaction old_act;
|
||||
new_act.sa_handler = handler;
|
||||
new_act.sa_flags = 0;
|
||||
new_act.sa_mask = 0;
|
||||
int rc = sigaction(signum, &new_act, &old_act);
|
||||
if (rc < 0)
|
||||
return SIG_ERR;
|
||||
return old_act.sa_handler;
|
||||
}
|
||||
|
||||
int sigaction(int signum, const struct sigaction* act, struct sigaction* old_act)
|
||||
{
|
||||
int rc = syscall(SC_sigaction, signum, act, old_act);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
|
||||
int sigemptyset(sigset_t* set)
|
||||
{
|
||||
*set = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sigfillset(sigset_t* set)
|
||||
{
|
||||
*set = 0xffffffff;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sigaddset(sigset_t* set, int sig)
|
||||
{
|
||||
if (sig < 1 || sig > 32) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
*set |= 1 << (sig - 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sigdelset(sigset_t* set, int sig)
|
||||
{
|
||||
if (sig < 1 || sig > 32) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
*set &= ~(1 << (sig - 1));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sigismember(const sigset_t* set, int sig)
|
||||
{
|
||||
if (sig < 1 || sig > 32) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (*set & (1 << (sig - 1)))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sigprocmask(int how, const sigset_t* set, sigset_t* old_set)
|
||||
{
|
||||
int rc = syscall(SC_sigprocmask, how, set, old_set);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
|
||||
int sigpending(sigset_t* set)
|
||||
{
|
||||
int rc = syscall(SC_sigpending, set);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
|
||||
const char* sys_siglist[NSIG] = {
|
||||
"Invalid signal number",
|
||||
"Hangup",
|
||||
"Interrupt",
|
||||
"Quit",
|
||||
"Illegal instruction",
|
||||
"Trap",
|
||||
"Aborted",
|
||||
"Bus error",
|
||||
"Division by zero",
|
||||
"Killed",
|
||||
"User signal 1",
|
||||
"Segmentation violation",
|
||||
"User signal 2",
|
||||
"Broken pipe",
|
||||
"Alarm clock",
|
||||
"Terminated",
|
||||
"Stack fault",
|
||||
"Child exited",
|
||||
"Continued",
|
||||
"Stopped (signal)",
|
||||
"Stopped",
|
||||
"Stopped (tty input)",
|
||||
"Stopped (tty output)",
|
||||
"Urgent I/O condition)",
|
||||
"CPU limit exceeded",
|
||||
"File size limit exceeded",
|
||||
"Virtual timer expired",
|
||||
"Profiling timer expired",
|
||||
"Window changed",
|
||||
"I/O possible",
|
||||
"Power failure",
|
||||
"Bad system call",
|
||||
};
|
||||
|
||||
int sigsetjmp(jmp_buf env, int savesigs)
|
||||
{
|
||||
if (savesigs) {
|
||||
int rc = sigprocmask(0, nullptr, &env->saved_signal_mask);
|
||||
assert(rc == 0);
|
||||
env->did_save_signal_mask = true;
|
||||
} else {
|
||||
env->did_save_signal_mask = false;
|
||||
}
|
||||
return setjmp(env);
|
||||
}
|
||||
void siglongjmp(jmp_buf env, int val)
|
||||
{
|
||||
if (env->did_save_signal_mask) {
|
||||
int rc = sigprocmask(SIG_SETMASK, &env->saved_signal_mask, nullptr);
|
||||
assert(rc == 0);
|
||||
}
|
||||
longjmp(env, val);
|
||||
}
|
||||
|
||||
int sigsuspend(const sigset_t*)
|
||||
{
|
||||
dbgprintf("FIXME: Implement sigsuspend()\n");
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
static const char* signal_names[] = {
|
||||
"INVAL",
|
||||
"HUP",
|
||||
"INT",
|
||||
"QUIT",
|
||||
"ILL",
|
||||
"TRAP",
|
||||
"ABRT",
|
||||
"BUS",
|
||||
"FPE",
|
||||
"KILL",
|
||||
"USR1",
|
||||
"SEGV",
|
||||
"USR2",
|
||||
"PIPE",
|
||||
"ALRM",
|
||||
"TERM",
|
||||
"STKFLT",
|
||||
"CHLD",
|
||||
"CONT",
|
||||
"STOP",
|
||||
"TSTP",
|
||||
"TTIN",
|
||||
"TTOU",
|
||||
"URG",
|
||||
"XCPU",
|
||||
"XFSZ",
|
||||
"VTALRM",
|
||||
"PROF",
|
||||
"WINCH",
|
||||
"IO",
|
||||
"INFO",
|
||||
"SYS",
|
||||
};
|
||||
|
||||
static_assert(sizeof(signal_names) == sizeof(const char*) * NSIG);
|
||||
|
||||
int getsignalbyname(const char* name)
|
||||
{
|
||||
ASSERT(name);
|
||||
for (size_t i = 0; i < NSIG; ++i) {
|
||||
auto* signal_name = signal_names[i];
|
||||
if (!strcmp(signal_name, name))
|
||||
return i;
|
||||
}
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char* getsignalname(int signal)
|
||||
{
|
||||
if (signal < 0 || signal >= NSIG) {
|
||||
errno = EINVAL;
|
||||
return nullptr;
|
||||
}
|
||||
return signal_names[signal];
|
||||
}
|
||||
}
|
109
Userland/Libraries/LibC/signal.h
Normal file
109
Userland/Libraries/LibC/signal.h
Normal file
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <signal_numbers.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
typedef void (*__sighandler_t)(int);
|
||||
typedef __sighandler_t sighandler_t;
|
||||
|
||||
typedef uint32_t sigset_t;
|
||||
typedef uint32_t sig_atomic_t;
|
||||
|
||||
union sigval {
|
||||
int sival_int;
|
||||
void* sival_ptr;
|
||||
};
|
||||
|
||||
typedef struct siginfo {
|
||||
int si_signo;
|
||||
int si_code;
|
||||
pid_t si_pid;
|
||||
uid_t si_uid;
|
||||
void* si_addr;
|
||||
int si_status;
|
||||
union sigval si_value;
|
||||
} siginfo_t;
|
||||
|
||||
struct sigaction {
|
||||
union {
|
||||
void (*sa_handler)(int);
|
||||
void (*sa_sigaction)(int, siginfo_t*, void*);
|
||||
};
|
||||
sigset_t sa_mask;
|
||||
int sa_flags;
|
||||
};
|
||||
|
||||
int kill(pid_t, int sig);
|
||||
int killpg(int pgrp, int sig);
|
||||
sighandler_t signal(int sig, sighandler_t);
|
||||
int pthread_sigmask(int how, const sigset_t* set, sigset_t* ol_dset);
|
||||
int sigaction(int sig, const struct sigaction* act, struct sigaction* old_act);
|
||||
int sigemptyset(sigset_t*);
|
||||
int sigfillset(sigset_t*);
|
||||
int sigaddset(sigset_t*, int sig);
|
||||
int sigdelset(sigset_t*, int sig);
|
||||
int sigismember(const sigset_t*, int sig);
|
||||
int sigprocmask(int how, const sigset_t* set, sigset_t* old_set);
|
||||
int sigpending(sigset_t*);
|
||||
int sigsuspend(const sigset_t*);
|
||||
int raise(int sig);
|
||||
int getsignalbyname(const char*);
|
||||
const char* getsignalname(int);
|
||||
|
||||
extern const char* sys_siglist[NSIG];
|
||||
|
||||
#define SIG_DFL ((__sighandler_t)0)
|
||||
#define SIG_ERR ((__sighandler_t)-1)
|
||||
#define SIG_IGN ((__sighandler_t)1)
|
||||
|
||||
#define SA_NOCLDSTOP 1
|
||||
#define SA_NOCLDWAIT 2
|
||||
#define SA_SIGINFO 4
|
||||
#define SA_ONSTACK 0x08000000
|
||||
#define SA_RESTART 0x10000000
|
||||
#define SA_NODEFER 0x40000000
|
||||
#define SA_RESETHAND 0x80000000
|
||||
|
||||
#define SA_NOMASK SA_NODEFER
|
||||
#define SA_ONESHOT SA_RESETHAND
|
||||
|
||||
#define SIG_BLOCK 0
|
||||
#define SIG_UNBLOCK 1
|
||||
#define SIG_SETMASK 2
|
||||
|
||||
#define CLD_EXITED 0
|
||||
#define CLD_KILLED 1
|
||||
#define CLD_DUMPED 2
|
||||
#define CLD_TRAPPED 3
|
||||
#define CLD_STOPPED 4
|
||||
#define CLD_CONTINUED 5
|
||||
|
||||
__END_DECLS
|
61
Userland/Libraries/LibC/signal_numbers.h
Normal file
61
Userland/Libraries/LibC/signal_numbers.h
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define SIGINVAL 0
|
||||
#define SIGHUP 1
|
||||
#define SIGINT 2
|
||||
#define SIGQUIT 3
|
||||
#define SIGILL 4
|
||||
#define SIGTRAP 5
|
||||
#define SIGABRT 6
|
||||
#define SIGBUS 7
|
||||
#define SIGFPE 8
|
||||
#define SIGKILL 9
|
||||
#define SIGUSR1 10
|
||||
#define SIGSEGV 11
|
||||
#define SIGUSR2 12
|
||||
#define SIGPIPE 13
|
||||
#define SIGALRM 14
|
||||
#define SIGTERM 15
|
||||
#define SIGSTKFLT 16
|
||||
#define SIGCHLD 17
|
||||
#define SIGCONT 18
|
||||
#define SIGSTOP 19
|
||||
#define SIGTSTP 20
|
||||
#define SIGTTIN 21
|
||||
#define SIGTTOU 22
|
||||
#define SIGURG 23
|
||||
#define SIGXCPU 24
|
||||
#define SIGXFSZ 25
|
||||
#define SIGVTALRM 26
|
||||
#define SIGPROF 27
|
||||
#define SIGWINCH 28
|
||||
#define SIGIO 29
|
||||
#define SIGINFO 30
|
||||
#define SIGSYS 31
|
||||
#define NSIG 32
|
289
Userland/Libraries/LibC/spawn.cpp
Normal file
289
Userland/Libraries/LibC/spawn.cpp
Normal file
|
@ -0,0 +1,289 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Nico Weber <thakis@chromium.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* posix_spawn and friends
|
||||
*
|
||||
* values from POSIX standard unix specification
|
||||
*
|
||||
* https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/spawn.h.html
|
||||
*/
|
||||
|
||||
#include <spawn.h>
|
||||
|
||||
#include <AK/Function.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
struct posix_spawn_file_actions_state {
|
||||
Vector<Function<int()>, 4> actions;
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
|
||||
[[noreturn]] static void posix_spawn_child(const char* path, const posix_spawn_file_actions_t* file_actions, const posix_spawnattr_t* attr, char* const argv[], char* const envp[], int (*exec)(const char*, char* const[], char* const[]))
|
||||
{
|
||||
if (attr) {
|
||||
short flags = attr->flags;
|
||||
if (flags & POSIX_SPAWN_RESETIDS) {
|
||||
if (seteuid(getuid()) < 0) {
|
||||
perror("posix_spawn seteuid");
|
||||
_exit(127);
|
||||
}
|
||||
if (setegid(getgid()) < 0) {
|
||||
perror("posix_spawn setegid");
|
||||
_exit(127);
|
||||
}
|
||||
}
|
||||
if (flags & POSIX_SPAWN_SETPGROUP) {
|
||||
if (setpgid(0, attr->pgroup) < 0) {
|
||||
perror("posix_spawn setpgid");
|
||||
_exit(127);
|
||||
}
|
||||
}
|
||||
if (flags & POSIX_SPAWN_SETSCHEDPARAM) {
|
||||
if (sched_setparam(0, &attr->schedparam) < 0) {
|
||||
perror("posix_spawn sched_setparam");
|
||||
_exit(127);
|
||||
}
|
||||
}
|
||||
if (flags & POSIX_SPAWN_SETSIGDEF) {
|
||||
struct sigaction default_action;
|
||||
default_action.sa_flags = 0;
|
||||
sigemptyset(&default_action.sa_mask);
|
||||
default_action.sa_handler = SIG_DFL;
|
||||
|
||||
sigset_t sigdefault = attr->sigdefault;
|
||||
for (int i = 0; i < NSIG; ++i) {
|
||||
if (sigismember(&sigdefault, i) && sigaction(i, &default_action, nullptr) < 0) {
|
||||
perror("posix_spawn sigaction");
|
||||
_exit(127);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (flags & POSIX_SPAWN_SETSIGMASK) {
|
||||
if (sigprocmask(SIG_SETMASK, &attr->sigmask, nullptr) < 0) {
|
||||
perror("posix_spawn sigprocmask");
|
||||
_exit(127);
|
||||
}
|
||||
}
|
||||
if (flags & POSIX_SPAWN_SETSID) {
|
||||
if (setsid() < 0) {
|
||||
perror("posix_spawn setsid");
|
||||
_exit(127);
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: POSIX_SPAWN_SETSCHEDULER
|
||||
}
|
||||
|
||||
if (file_actions) {
|
||||
for (const auto& action : file_actions->state->actions) {
|
||||
if (action() < 0) {
|
||||
perror("posix_spawn file action");
|
||||
_exit(127);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exec(path, argv, envp);
|
||||
perror("posix_spawn exec");
|
||||
_exit(127);
|
||||
}
|
||||
|
||||
int posix_spawn(pid_t* out_pid, const char* path, const posix_spawn_file_actions_t* file_actions, const posix_spawnattr_t* attr, char* const argv[], char* const envp[])
|
||||
{
|
||||
pid_t child_pid = fork();
|
||||
if (child_pid < 0)
|
||||
return errno;
|
||||
|
||||
if (child_pid != 0) {
|
||||
*out_pid = child_pid;
|
||||
return 0;
|
||||
}
|
||||
|
||||
posix_spawn_child(path, file_actions, attr, argv, envp, execve);
|
||||
}
|
||||
|
||||
int posix_spawnp(pid_t* out_pid, const char* path, const posix_spawn_file_actions_t* file_actions, const posix_spawnattr_t* attr, char* const argv[], char* const envp[])
|
||||
{
|
||||
pid_t child_pid = fork();
|
||||
if (child_pid < 0)
|
||||
return errno;
|
||||
|
||||
if (child_pid != 0) {
|
||||
*out_pid = child_pid;
|
||||
return 0;
|
||||
}
|
||||
|
||||
posix_spawn_child(path, file_actions, attr, argv, envp, execvpe);
|
||||
}
|
||||
|
||||
int posix_spawn_file_actions_addchdir(posix_spawn_file_actions_t* actions, const char* path)
|
||||
{
|
||||
actions->state->actions.append([path]() { return chdir(path); });
|
||||
return 0;
|
||||
}
|
||||
|
||||
int posix_spawn_file_actions_addfchdir(posix_spawn_file_actions_t* actions, int fd)
|
||||
{
|
||||
actions->state->actions.append([fd]() { return fchdir(fd); });
|
||||
return 0;
|
||||
}
|
||||
|
||||
int posix_spawn_file_actions_addclose(posix_spawn_file_actions_t* actions, int fd)
|
||||
{
|
||||
actions->state->actions.append([fd]() { return close(fd); });
|
||||
return 0;
|
||||
}
|
||||
|
||||
int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t* actions, int old_fd, int new_fd)
|
||||
{
|
||||
actions->state->actions.append([old_fd, new_fd]() { return dup2(old_fd, new_fd); });
|
||||
return 0;
|
||||
}
|
||||
|
||||
int posix_spawn_file_actions_addopen(posix_spawn_file_actions_t* actions, int want_fd, const char* path, int flags, mode_t mode)
|
||||
{
|
||||
actions->state->actions.append([want_fd, path, flags, mode]() {
|
||||
int opened_fd = open(path, flags, mode);
|
||||
if (opened_fd < 0 || opened_fd == want_fd)
|
||||
return opened_fd;
|
||||
if (int rc = dup2(opened_fd, want_fd); rc < 0)
|
||||
return rc;
|
||||
return close(opened_fd);
|
||||
});
|
||||
return 0;
|
||||
}
|
||||
|
||||
int posix_spawn_file_actions_destroy(posix_spawn_file_actions_t* actions)
|
||||
{
|
||||
delete actions->state;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int posix_spawn_file_actions_init(posix_spawn_file_actions_t* actions)
|
||||
{
|
||||
actions->state = new posix_spawn_file_actions_state;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int posix_spawnattr_destroy(posix_spawnattr_t*)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int posix_spawnattr_getflags(const posix_spawnattr_t* attr, short* out_flags)
|
||||
{
|
||||
*out_flags = attr->flags;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int posix_spawnattr_getpgroup(const posix_spawnattr_t* attr, pid_t* out_pgroup)
|
||||
{
|
||||
*out_pgroup = attr->pgroup;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int posix_spawnattr_getschedparam(const posix_spawnattr_t* attr, struct sched_param* out_schedparam)
|
||||
{
|
||||
*out_schedparam = attr->schedparam;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int posix_spawnattr_getschedpolicy(const posix_spawnattr_t* attr, int* out_schedpolicty)
|
||||
{
|
||||
*out_schedpolicty = attr->schedpolicy;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int posix_spawnattr_getsigdefault(const posix_spawnattr_t* attr, sigset_t* out_sigdefault)
|
||||
{
|
||||
*out_sigdefault = attr->sigdefault;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int posix_spawnattr_getsigmask(const posix_spawnattr_t* attr, sigset_t* out_sigmask)
|
||||
{
|
||||
*out_sigmask = attr->sigmask;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int posix_spawnattr_init(posix_spawnattr_t* attr)
|
||||
{
|
||||
attr->flags = 0;
|
||||
attr->pgroup = 0;
|
||||
// attr->schedparam intentionally not written; its default value is unspecified.
|
||||
// attr->schedpolicy intentionally not written; its default value is unspecified.
|
||||
sigemptyset(&attr->sigdefault);
|
||||
// attr->sigmask intentionally not written; its default value is unspecified.
|
||||
return 0;
|
||||
}
|
||||
|
||||
int posix_spawnattr_setflags(posix_spawnattr_t* attr, short flags)
|
||||
{
|
||||
if (flags & ~(POSIX_SPAWN_RESETIDS | POSIX_SPAWN_SETPGROUP | POSIX_SPAWN_SETSCHEDPARAM | POSIX_SPAWN_SETSCHEDULER | POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK | POSIX_SPAWN_SETSID))
|
||||
return EINVAL;
|
||||
|
||||
attr->flags = flags;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int posix_spawnattr_setpgroup(posix_spawnattr_t* attr, pid_t pgroup)
|
||||
{
|
||||
attr->pgroup = pgroup;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int posix_spawnattr_setschedparam(posix_spawnattr_t* attr, const struct sched_param* schedparam)
|
||||
{
|
||||
attr->schedparam = *schedparam;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int posix_spawnattr_setschedpolicy(posix_spawnattr_t* attr, int schedpolicy)
|
||||
{
|
||||
attr->schedpolicy = schedpolicy;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int posix_spawnattr_setsigdefault(posix_spawnattr_t* attr, const sigset_t* sigdefault)
|
||||
{
|
||||
attr->sigdefault = *sigdefault;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int posix_spawnattr_setsigmask(posix_spawnattr_t* attr, const sigset_t* sigmask)
|
||||
{
|
||||
attr->sigmask = *sigmask;
|
||||
return 0;
|
||||
}
|
||||
}
|
99
Userland/Libraries/LibC/spawn.h
Normal file
99
Userland/Libraries/LibC/spawn.h
Normal file
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Nico Weber <thakis@chromium.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* posix_spawn and friends
|
||||
*
|
||||
* values from POSIX standard unix specification
|
||||
*
|
||||
* https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/spawn.h.html
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <sched.h>
|
||||
#include <signal.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
enum {
|
||||
POSIX_SPAWN_RESETIDS = 1 << 0,
|
||||
POSIX_SPAWN_SETPGROUP = 1 << 1,
|
||||
|
||||
POSIX_SPAWN_SETSCHEDPARAM = 1 << 2,
|
||||
POSIX_SPAWN_SETSCHEDULER = 1 << 3,
|
||||
|
||||
POSIX_SPAWN_SETSIGDEF = 1 << 4,
|
||||
POSIX_SPAWN_SETSIGMASK = 1 << 5,
|
||||
|
||||
POSIX_SPAWN_SETSID = 1 << 6,
|
||||
};
|
||||
|
||||
#define POSIX_SPAWN_SETSID POSIX_SPAWN_SETSID
|
||||
|
||||
struct posix_spawn_file_actions_state;
|
||||
typedef struct {
|
||||
struct posix_spawn_file_actions_state* state;
|
||||
} posix_spawn_file_actions_t;
|
||||
|
||||
typedef struct {
|
||||
short flags;
|
||||
pid_t pgroup;
|
||||
struct sched_param schedparam;
|
||||
int schedpolicy;
|
||||
sigset_t sigdefault;
|
||||
sigset_t sigmask;
|
||||
} posix_spawnattr_t;
|
||||
|
||||
int posix_spawn(pid_t*, const char*, const posix_spawn_file_actions_t*, const posix_spawnattr_t*, char* const argv[], char* const envp[]);
|
||||
int posix_spawnp(pid_t*, const char*, const posix_spawn_file_actions_t*, const posix_spawnattr_t*, char* const argv[], char* const envp[]);
|
||||
|
||||
int posix_spawn_file_actions_addchdir(posix_spawn_file_actions_t*, const char*);
|
||||
int posix_spawn_file_actions_addfchdir(posix_spawn_file_actions_t*, int);
|
||||
int posix_spawn_file_actions_addclose(posix_spawn_file_actions_t*, int);
|
||||
int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t*, int old_fd, int new_fd);
|
||||
int posix_spawn_file_actions_addopen(posix_spawn_file_actions_t*, int fd, const char*, int flags, mode_t);
|
||||
int posix_spawn_file_actions_destroy(posix_spawn_file_actions_t*);
|
||||
int posix_spawn_file_actions_init(posix_spawn_file_actions_t*);
|
||||
|
||||
int posix_spawnattr_destroy(posix_spawnattr_t*);
|
||||
int posix_spawnattr_getflags(const posix_spawnattr_t*, short*);
|
||||
int posix_spawnattr_getpgroup(const posix_spawnattr_t*, pid_t*);
|
||||
int posix_spawnattr_getschedparam(const posix_spawnattr_t*, struct sched_param*);
|
||||
int posix_spawnattr_getschedpolicy(const posix_spawnattr_t*, int*);
|
||||
int posix_spawnattr_getsigdefault(const posix_spawnattr_t*, sigset_t*);
|
||||
int posix_spawnattr_getsigmask(const posix_spawnattr_t*, sigset_t*);
|
||||
int posix_spawnattr_init(posix_spawnattr_t*);
|
||||
int posix_spawnattr_setflags(posix_spawnattr_t*, short);
|
||||
int posix_spawnattr_setpgroup(posix_spawnattr_t*, pid_t);
|
||||
int posix_spawnattr_setschedparam(posix_spawnattr_t*, const struct sched_param*);
|
||||
int posix_spawnattr_setschedpolicy(posix_spawnattr_t*, int);
|
||||
int posix_spawnattr_setsigdefault(posix_spawnattr_t*, const sigset_t*);
|
||||
int posix_spawnattr_setsigmask(posix_spawnattr_t*, const sigset_t*);
|
||||
|
||||
__END_DECLS
|
55
Userland/Libraries/LibC/ssp.cpp
Normal file
55
Userland/Libraries/LibC/ssp.cpp
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Brian Gianforcaro <b.gianfo@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <AK/Types.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/internals.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if defined __SSP__ || defined __SSP_ALL__
|
||||
# error "file must not be compiled with stack protection enabled on it. Use -fno-stack-protector"
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
|
||||
extern u32 __stack_chk_guard;
|
||||
u32 __stack_chk_guard = (u32)0xc6c7c8c9;
|
||||
|
||||
[[noreturn]] void __stack_chk_fail()
|
||||
{
|
||||
dbgprintf("Error: USERSPACE(%d) Stack protector failure, stack smashing detected!\n", getpid());
|
||||
if (__stdio_is_initialized)
|
||||
fprintf(stderr, "Error: Stack protector failure, stack smashing detected!\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
[[noreturn]] void __stack_chk_fail_local()
|
||||
{
|
||||
__stack_chk_fail();
|
||||
}
|
||||
|
||||
} // extern "C"
|
99
Userland/Libraries/LibC/stat.cpp
Normal file
99
Userland/Libraries/LibC/stat.cpp
Normal file
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <Kernel/API/Syscall.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
mode_t umask(mode_t mask)
|
||||
{
|
||||
return syscall(SC_umask, mask);
|
||||
}
|
||||
|
||||
int mkdir(const char* pathname, mode_t mode)
|
||||
{
|
||||
if (!pathname) {
|
||||
errno = EFAULT;
|
||||
return -1;
|
||||
}
|
||||
int rc = syscall(SC_mkdir, pathname, strlen(pathname), mode);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
|
||||
int chmod(const char* pathname, mode_t mode)
|
||||
{
|
||||
if (!pathname) {
|
||||
errno = EFAULT;
|
||||
return -1;
|
||||
}
|
||||
int rc = syscall(SC_chmod, pathname, strlen(pathname), mode);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
|
||||
int fchmod(int fd, mode_t mode)
|
||||
{
|
||||
int rc = syscall(SC_fchmod, fd, mode);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
|
||||
int mkfifo(const char* pathname, mode_t mode)
|
||||
{
|
||||
return mknod(pathname, mode | S_IFIFO, 0);
|
||||
}
|
||||
|
||||
static int do_stat(const char* path, struct stat* statbuf, bool follow_symlinks)
|
||||
{
|
||||
if (!path) {
|
||||
errno = EFAULT;
|
||||
return -1;
|
||||
}
|
||||
Syscall::SC_stat_params params { { path, strlen(path) }, statbuf, follow_symlinks };
|
||||
int rc = syscall(SC_stat, ¶ms);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
|
||||
int lstat(const char* path, struct stat* statbuf)
|
||||
{
|
||||
return do_stat(path, statbuf, false);
|
||||
}
|
||||
|
||||
int stat(const char* path, struct stat* statbuf)
|
||||
{
|
||||
return do_stat(path, statbuf, true);
|
||||
}
|
||||
|
||||
int fstat(int fd, struct stat* statbuf)
|
||||
{
|
||||
int rc = syscall(SC_fstat, fd, statbuf);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
}
|
44
Userland/Libraries/LibC/stdarg.h
Normal file
44
Userland/Libraries/LibC/stdarg.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if defined(KERNEL)
|
||||
# define __BEGIN_DECLS
|
||||
# define __END_DECLS
|
||||
#else
|
||||
# include <sys/cdefs.h>
|
||||
#endif
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
typedef __builtin_va_list va_list;
|
||||
|
||||
#define va_start(v, l) __builtin_va_start(v, l)
|
||||
#define va_end(v) __builtin_va_end(v)
|
||||
#define va_arg(v, l) __builtin_va_arg(v, l)
|
||||
|
||||
__END_DECLS
|
42
Userland/Libraries/LibC/stdbool.h
Normal file
42
Userland/Libraries/LibC/stdbool.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __cplusplus
|
||||
|
||||
# include <sys/cdefs.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
# define bool _Bool
|
||||
# define true 1
|
||||
# define false 0
|
||||
# define __bool_true_false_are_Defined 1
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif
|
42
Userland/Libraries/LibC/stddef.h
Normal file
42
Userland/Libraries/LibC/stddef.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef KERNEL
|
||||
|
||||
# include <sys/cdefs.h>
|
||||
|
||||
# ifdef __cplusplus
|
||||
# define NULL nullptr
|
||||
# else
|
||||
# define NULL ((void*)0)
|
||||
# endif
|
||||
|
||||
typedef __PTRDIFF_TYPE__ ptrdiff_t;
|
||||
typedef __SIZE_TYPE__ size_t;
|
||||
|
||||
#endif
|
31
Userland/Libraries/LibC/stdint.h
Normal file
31
Userland/Libraries/LibC/stdint.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#include <bits/stdint.h>
|
1219
Userland/Libraries/LibC/stdio.cpp
Normal file
1219
Userland/Libraries/LibC/stdio.cpp
Normal file
File diff suppressed because it is too large
Load diff
120
Userland/Libraries/LibC/stdio.h
Normal file
120
Userland/Libraries/LibC/stdio.h
Normal file
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define _STDIO_H // Make GMP believe we exist.
|
||||
|
||||
#include <bits/FILE.h>
|
||||
#include <limits.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#define FILENAME_MAX 1024
|
||||
|
||||
__BEGIN_DECLS
|
||||
#ifndef EOF
|
||||
# define EOF (-1)
|
||||
#endif
|
||||
|
||||
#define SEEK_SET 0
|
||||
#define SEEK_CUR 1
|
||||
#define SEEK_END 2
|
||||
|
||||
#define _IOFBF 0
|
||||
#define _IOLBF 1
|
||||
#define _IONBF 2
|
||||
|
||||
#define L_tmpnam 256
|
||||
|
||||
extern FILE* stdin;
|
||||
extern FILE* stdout;
|
||||
extern FILE* stderr;
|
||||
|
||||
typedef off_t fpos_t;
|
||||
|
||||
int fseek(FILE*, long offset, int whence);
|
||||
int fseeko(FILE*, off_t offset, int whence);
|
||||
int fgetpos(FILE*, fpos_t*);
|
||||
int fsetpos(FILE*, const fpos_t*);
|
||||
long ftell(FILE*);
|
||||
off_t ftello(FILE*);
|
||||
char* fgets(char* buffer, int size, FILE*);
|
||||
int fputc(int ch, FILE*);
|
||||
int fileno(FILE*);
|
||||
int fgetc(FILE*);
|
||||
int getc(FILE*);
|
||||
int getc_unlocked(FILE* stream);
|
||||
int getchar();
|
||||
ssize_t getdelim(char**, size_t*, int, FILE*);
|
||||
ssize_t getline(char**, size_t*, FILE*);
|
||||
int ungetc(int c, FILE*);
|
||||
int remove(const char* pathname);
|
||||
FILE* fdopen(int fd, const char* mode);
|
||||
FILE* fopen(const char* pathname, const char* mode);
|
||||
FILE* freopen(const char* pathname, const char* mode, FILE*);
|
||||
void flockfile(FILE* filehandle);
|
||||
void funlockfile(FILE* filehandle);
|
||||
int fclose(FILE*);
|
||||
void rewind(FILE*);
|
||||
void clearerr(FILE*);
|
||||
int ferror(FILE*);
|
||||
int feof(FILE*);
|
||||
int fflush(FILE*);
|
||||
size_t fread(void* ptr, size_t size, size_t nmemb, FILE*);
|
||||
size_t fwrite(const void* ptr, size_t size, size_t nmemb, FILE*);
|
||||
int vprintf(const char* fmt, va_list) __attribute__((format(printf, 1, 0)));
|
||||
int vfprintf(FILE*, const char* fmt, va_list) __attribute__((format(printf, 2, 0)));
|
||||
int vsprintf(char* buffer, const char* fmt, va_list) __attribute__((format(printf, 2, 0)));
|
||||
int vsnprintf(char* buffer, size_t, const char* fmt, va_list) __attribute__((format(printf, 3, 0)));
|
||||
int fprintf(FILE*, const char* fmt, ...) __attribute__((format(printf, 2, 3)));
|
||||
int printf(const char* fmt, ...) __attribute__((format(printf, 1, 2)));
|
||||
int dbgprintf(const char* fmt, ...) __attribute__((format(printf, 1, 2)));
|
||||
void dbgputch(char);
|
||||
int dbgputstr(const char*, ssize_t);
|
||||
int sprintf(char* buffer, const char* fmt, ...) __attribute__((format(printf, 2, 3)));
|
||||
int snprintf(char* buffer, size_t, const char* fmt, ...) __attribute__((format(printf, 3, 4)));
|
||||
int putchar(int ch);
|
||||
int putc(int ch, FILE*);
|
||||
int puts(const char*);
|
||||
int fputs(const char*, FILE*);
|
||||
void perror(const char*);
|
||||
int scanf(const char* fmt, ...) __attribute__((format(scanf, 1, 2)));
|
||||
int sscanf(const char* str, const char* fmt, ...) __attribute__((format(scanf, 2, 3)));
|
||||
int fscanf(FILE*, const char* fmt, ...) __attribute__((format(scanf, 2, 3)));
|
||||
int vfscanf(FILE*, const char*, va_list) __attribute__((format(scanf, 2, 0)));
|
||||
int vsscanf(const char*, const char*, va_list) __attribute__((format(scanf, 2, 0)));
|
||||
int setvbuf(FILE*, char* buf, int mode, size_t);
|
||||
void setbuf(FILE*, char* buf);
|
||||
void setlinebuf(FILE*);
|
||||
int rename(const char* oldpath, const char* newpath);
|
||||
FILE* tmpfile();
|
||||
char* tmpnam(char*);
|
||||
FILE* popen(const char* command, const char* type);
|
||||
int pclose(FILE*);
|
||||
|
||||
__END_DECLS
|
1083
Userland/Libraries/LibC/stdlib.cpp
Normal file
1083
Userland/Libraries/LibC/stdlib.cpp
Normal file
File diff suppressed because it is too large
Load diff
109
Userland/Libraries/LibC/stdlib.h
Normal file
109
Userland/Libraries/LibC/stdlib.h
Normal file
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
__attribute__((warn_unused_result)) int __generate_unique_filename(char* pattern);
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
#define EXIT_SUCCESS 0
|
||||
#define EXIT_FAILURE 1
|
||||
#define MB_CUR_MAX 1
|
||||
|
||||
__attribute__((malloc)) __attribute__((alloc_size(1))) void* malloc(size_t);
|
||||
__attribute__((malloc)) __attribute__((alloc_size(1, 2))) void* calloc(size_t nmemb, size_t);
|
||||
size_t malloc_size(void*);
|
||||
void serenity_dump_malloc_stats(void);
|
||||
void free(void*);
|
||||
__attribute__((alloc_size(2))) void* realloc(void* ptr, size_t);
|
||||
char* getenv(const char* name);
|
||||
int putenv(char*);
|
||||
int unsetenv(const char*);
|
||||
int clearenv(void);
|
||||
int setenv(const char* name, const char* value, int overwrite);
|
||||
int atoi(const char*);
|
||||
long atol(const char*);
|
||||
long long atoll(const char*);
|
||||
double strtod(const char*, char** endptr);
|
||||
long double strtold(const char*, char** endptr);
|
||||
float strtof(const char*, char** endptr);
|
||||
long strtol(const char*, char** endptr, int base);
|
||||
long long strtoll(const char*, char** endptr, int base);
|
||||
unsigned long long strtoull(const char*, char** endptr, int base);
|
||||
unsigned long strtoul(const char*, char** endptr, int base);
|
||||
void qsort(void* base, size_t nmemb, size_t size, int (*compar)(const void*, const void*));
|
||||
void qsort_r(void* base, size_t nmemb, size_t size, int (*compar)(const void*, const void*, void*), void* arg);
|
||||
int atexit(void (*function)());
|
||||
__attribute__((noreturn)) void exit(int status);
|
||||
__attribute__((noreturn)) void abort();
|
||||
char* ptsname(int fd);
|
||||
int ptsname_r(int fd, char* buffer, size_t);
|
||||
int abs(int);
|
||||
long labs(long);
|
||||
double atof(const char*);
|
||||
int system(const char* command);
|
||||
char* mktemp(char*);
|
||||
int mkstemp(char*);
|
||||
char* mkdtemp(char*);
|
||||
void* bsearch(const void* key, const void* base, size_t nmemb, size_t size, int (*compar)(const void*, const void*));
|
||||
size_t mbstowcs(wchar_t*, const char*, size_t);
|
||||
int mbtowc(wchar_t*, const char*, size_t);
|
||||
int wctomb(char*, wchar_t);
|
||||
size_t wcstombs(char*, const wchar_t*, size_t);
|
||||
char* realpath(const char* pathname, char* buffer);
|
||||
|
||||
#define RAND_MAX 32767
|
||||
int rand();
|
||||
void srand(unsigned seed);
|
||||
|
||||
long int random();
|
||||
void srandom(unsigned seed);
|
||||
|
||||
uint32_t arc4random(void);
|
||||
void arc4random_buf(void*, size_t);
|
||||
uint32_t arc4random_uniform(uint32_t);
|
||||
|
||||
typedef struct {
|
||||
int quot;
|
||||
int rem;
|
||||
} div_t;
|
||||
div_t div(int, int);
|
||||
typedef struct {
|
||||
long quot;
|
||||
long rem;
|
||||
} ldiv_t;
|
||||
ldiv_t ldiv(long, long);
|
||||
|
||||
int posix_openpt(int flags);
|
||||
int grantpt(int fd);
|
||||
int unlockpt(int fd);
|
||||
|
||||
__END_DECLS
|
486
Userland/Libraries/LibC/string.cpp
Normal file
486
Userland/Libraries/LibC/string.cpp
Normal file
|
@ -0,0 +1,486 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <AK/MemMem.h>
|
||||
#include <AK/Platform.h>
|
||||
#include <AK/StdLibExtras.h>
|
||||
#include <AK/Types.h>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
size_t strspn(const char* s, const char* accept)
|
||||
{
|
||||
const char* p = s;
|
||||
cont:
|
||||
char ch = *p++;
|
||||
char ac;
|
||||
for (const char* ap = accept; (ac = *ap++) != '\0';) {
|
||||
if (ac == ch)
|
||||
goto cont;
|
||||
}
|
||||
return p - 1 - s;
|
||||
}
|
||||
|
||||
size_t strcspn(const char* s, const char* reject)
|
||||
{
|
||||
for (auto* p = s;;) {
|
||||
char c = *p++;
|
||||
auto* rp = reject;
|
||||
char rc;
|
||||
do {
|
||||
if ((rc = *rp++) == c)
|
||||
return p - 1 - s;
|
||||
} while (rc);
|
||||
}
|
||||
}
|
||||
|
||||
size_t strlen(const char* str)
|
||||
{
|
||||
size_t len = 0;
|
||||
while (*(str++))
|
||||
++len;
|
||||
return len;
|
||||
}
|
||||
|
||||
size_t strnlen(const char* str, size_t maxlen)
|
||||
{
|
||||
size_t len = 0;
|
||||
for (; len < maxlen && *str; str++)
|
||||
len++;
|
||||
return len;
|
||||
}
|
||||
|
||||
char* strdup(const char* str)
|
||||
{
|
||||
size_t len = strlen(str);
|
||||
char* new_str = (char*)malloc(len + 1);
|
||||
memcpy(new_str, str, len);
|
||||
new_str[len] = '\0';
|
||||
return new_str;
|
||||
}
|
||||
|
||||
char* strndup(const char* str, size_t maxlen)
|
||||
{
|
||||
size_t len = strnlen(str, maxlen);
|
||||
char* new_str = (char*)malloc(len + 1);
|
||||
memcpy(new_str, str, len);
|
||||
new_str[len] = 0;
|
||||
return new_str;
|
||||
}
|
||||
|
||||
int strcmp(const char* s1, const char* s2)
|
||||
{
|
||||
while (*s1 == *s2++)
|
||||
if (*s1++ == 0)
|
||||
return 0;
|
||||
return *(const unsigned char*)s1 - *(const unsigned char*)--s2;
|
||||
}
|
||||
|
||||
int strncmp(const char* s1, const char* s2, size_t n)
|
||||
{
|
||||
if (!n)
|
||||
return 0;
|
||||
do {
|
||||
if (*s1 != *s2++)
|
||||
return *(const unsigned char*)s1 - *(const unsigned char*)--s2;
|
||||
if (*s1++ == 0)
|
||||
break;
|
||||
} while (--n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int memcmp(const void* v1, const void* v2, size_t n)
|
||||
{
|
||||
auto* s1 = (const uint8_t*)v1;
|
||||
auto* s2 = (const uint8_t*)v2;
|
||||
while (n-- > 0) {
|
||||
if (*s1++ != *s2++)
|
||||
return s1[-1] < s2[-1] ? -1 : 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if ARCH(I386)
|
||||
void* memcpy(void* dest_ptr, const void* src_ptr, size_t n)
|
||||
{
|
||||
void* original_dest = dest_ptr;
|
||||
asm volatile(
|
||||
"rep movsb"
|
||||
: "+D"(dest_ptr), "+S"(src_ptr), "+c"(n)::"memory");
|
||||
return original_dest;
|
||||
}
|
||||
|
||||
void* memset(void* dest_ptr, int c, size_t n)
|
||||
{
|
||||
void* original_dest = dest_ptr;
|
||||
asm volatile(
|
||||
"rep stosb\n"
|
||||
: "=D"(dest_ptr), "=c"(n)
|
||||
: "0"(dest_ptr), "1"(n), "a"(c)
|
||||
: "memory");
|
||||
return original_dest;
|
||||
}
|
||||
#else
|
||||
void* memcpy(void* dest_ptr, const void* src_ptr, size_t n)
|
||||
{
|
||||
auto* dest = (u8*)dest_ptr;
|
||||
auto* src = (const u8*)src_ptr;
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
dest[i] = src[i];
|
||||
return dest_ptr;
|
||||
}
|
||||
|
||||
void* memset(void* dest_ptr, int c, size_t n)
|
||||
{
|
||||
auto* dest = (u8*)dest_ptr;
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
dest[i] = (u8)c;
|
||||
return dest_ptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
void* memmove(void* dest, const void* src, size_t n)
|
||||
{
|
||||
if (dest < src)
|
||||
return memcpy(dest, src, n);
|
||||
|
||||
u8* pd = (u8*)dest;
|
||||
const u8* ps = (const u8*)src;
|
||||
for (pd += n, ps += n; n--;)
|
||||
*--pd = *--ps;
|
||||
return dest;
|
||||
}
|
||||
|
||||
const void* memmem(const void* haystack, size_t haystack_length, const void* needle, size_t needle_length)
|
||||
{
|
||||
return AK::memmem(haystack, haystack_length, needle, needle_length);
|
||||
}
|
||||
|
||||
char* strcpy(char* dest, const char* src)
|
||||
{
|
||||
char* originalDest = dest;
|
||||
while ((*dest++ = *src++) != '\0')
|
||||
;
|
||||
return originalDest;
|
||||
}
|
||||
|
||||
char* strncpy(char* dest, const char* src, size_t n)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < n && src[i] != '\0'; ++i)
|
||||
dest[i] = src[i];
|
||||
for (; i < n; ++i)
|
||||
dest[i] = '\0';
|
||||
return dest;
|
||||
}
|
||||
|
||||
size_t strlcpy(char* dest, const char* src, size_t n)
|
||||
{
|
||||
size_t i;
|
||||
// Would like to test i < n - 1 here, but n might be 0.
|
||||
for (i = 0; i + 1 < n && src[i] != '\0'; ++i)
|
||||
dest[i] = src[i];
|
||||
if (n)
|
||||
dest[i] = '\0';
|
||||
for (; src[i] != '\0'; ++i)
|
||||
; // Determine the length of src, don't copy.
|
||||
return i;
|
||||
}
|
||||
|
||||
char* strchr(const char* str, int c)
|
||||
{
|
||||
char ch = c;
|
||||
for (;; ++str) {
|
||||
if (*str == ch)
|
||||
return const_cast<char*>(str);
|
||||
if (!*str)
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
char* strchrnul(const char* str, int c)
|
||||
{
|
||||
char ch = c;
|
||||
for (;; ++str) {
|
||||
if (*str == ch || !*str)
|
||||
return const_cast<char*>(str);
|
||||
}
|
||||
}
|
||||
|
||||
void* memchr(const void* ptr, int c, size_t size)
|
||||
{
|
||||
char ch = c;
|
||||
auto* cptr = (const char*)ptr;
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
if (cptr[i] == ch)
|
||||
return const_cast<char*>(cptr + i);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
char* strrchr(const char* str, int ch)
|
||||
{
|
||||
char* last = nullptr;
|
||||
char c;
|
||||
for (; (c = *str); ++str) {
|
||||
if (c == ch)
|
||||
last = const_cast<char*>(str);
|
||||
}
|
||||
return last;
|
||||
}
|
||||
|
||||
char* strcat(char* dest, const char* src)
|
||||
{
|
||||
size_t dest_length = strlen(dest);
|
||||
size_t i;
|
||||
for (i = 0; src[i] != '\0'; i++)
|
||||
dest[dest_length + i] = src[i];
|
||||
dest[dest_length + i] = '\0';
|
||||
return dest;
|
||||
}
|
||||
|
||||
char* strncat(char* dest, const char* src, size_t n)
|
||||
{
|
||||
size_t dest_length = strlen(dest);
|
||||
size_t i;
|
||||
for (i = 0; i < n && src[i] != '\0'; i++)
|
||||
dest[dest_length + i] = src[i];
|
||||
dest[dest_length + i] = '\0';
|
||||
return dest;
|
||||
}
|
||||
|
||||
const char* const sys_errlist[] = {
|
||||
"Success (not an error)",
|
||||
"Operation not permitted",
|
||||
"No such file or directory",
|
||||
"No such process",
|
||||
"Interrupted syscall",
|
||||
"I/O error",
|
||||
"No such device or address",
|
||||
"Argument list too long",
|
||||
"Exec format error",
|
||||
"Bad fd number",
|
||||
"No child processes",
|
||||
"Try again",
|
||||
"Out of memory",
|
||||
"Permission denied",
|
||||
"Bad address",
|
||||
"Block device required",
|
||||
"Device or resource busy",
|
||||
"File already exists",
|
||||
"Cross-device link",
|
||||
"No such device",
|
||||
"Not a directory",
|
||||
"Is a directory",
|
||||
"Invalid argument",
|
||||
"File table overflow",
|
||||
"Too many open files",
|
||||
"Not a TTY",
|
||||
"Text file busy",
|
||||
"File too large",
|
||||
"No space left on device",
|
||||
"Illegal seek",
|
||||
"Read-only filesystem",
|
||||
"Too many links",
|
||||
"Broken pipe",
|
||||
"Range error",
|
||||
"Name too long",
|
||||
"Too many symlinks",
|
||||
"Overflow",
|
||||
"Operation not supported",
|
||||
"No such syscall",
|
||||
"Not implemented",
|
||||
"Address family not supported",
|
||||
"Not a socket",
|
||||
"Address in use",
|
||||
"Failed without setting an error code (bug!)",
|
||||
"Directory not empty",
|
||||
"Math argument out of domain",
|
||||
"Connection refused",
|
||||
"Address not available",
|
||||
"Already connected",
|
||||
"Connection aborted",
|
||||
"Connection already in progress",
|
||||
"Connection reset",
|
||||
"Destination address required",
|
||||
"Host unreachable",
|
||||
"Illegal byte sequence",
|
||||
"Message size",
|
||||
"Network down",
|
||||
"Network unreachable",
|
||||
"Network reset",
|
||||
"No buffer space",
|
||||
"No lock available",
|
||||
"No message",
|
||||
"No protocol option",
|
||||
"Not connected",
|
||||
"Operation would block",
|
||||
"Protocol not supported",
|
||||
"Resource deadlock would occur",
|
||||
"Timed out",
|
||||
"Wrong protocol type",
|
||||
"Operation in progress",
|
||||
"No such thread",
|
||||
"Protocol error",
|
||||
"Not supported",
|
||||
"Protocol family not supported",
|
||||
"Cannot make directory a subdirectory of itself",
|
||||
"The highest errno +1 :^)",
|
||||
};
|
||||
|
||||
int sys_nerr = EMAXERRNO;
|
||||
|
||||
char* strerror(int errnum)
|
||||
{
|
||||
if (errnum < 0 || errnum >= EMAXERRNO) {
|
||||
printf("strerror() missing string for errnum=%d\n", errnum);
|
||||
return const_cast<char*>("Unknown error");
|
||||
}
|
||||
return const_cast<char*>(sys_errlist[errnum]);
|
||||
}
|
||||
|
||||
char* strsignal(int signum)
|
||||
{
|
||||
if (signum >= NSIG) {
|
||||
printf("strsignal() missing string for signum=%d\n", signum);
|
||||
return const_cast<char*>("Unknown signal");
|
||||
}
|
||||
return const_cast<char*>(sys_siglist[signum]);
|
||||
}
|
||||
|
||||
char* strstr(const char* haystack, const char* needle)
|
||||
{
|
||||
char nch;
|
||||
char hch;
|
||||
|
||||
if ((nch = *needle++) != 0) {
|
||||
size_t len = strlen(needle);
|
||||
do {
|
||||
do {
|
||||
if ((hch = *haystack++) == 0)
|
||||
return nullptr;
|
||||
} while (hch != nch);
|
||||
} while (strncmp(haystack, needle, len) != 0);
|
||||
--haystack;
|
||||
}
|
||||
return const_cast<char*>(haystack);
|
||||
}
|
||||
|
||||
char* strpbrk(const char* s, const char* accept)
|
||||
{
|
||||
while (*s)
|
||||
if (strchr(accept, *s++))
|
||||
return const_cast<char*>(--s);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
char* strtok_r(char* str, const char* delim, char** saved_str)
|
||||
{
|
||||
if (!str) {
|
||||
if (!saved_str)
|
||||
return nullptr;
|
||||
str = *saved_str;
|
||||
}
|
||||
|
||||
size_t token_start = 0;
|
||||
size_t token_end = 0;
|
||||
size_t str_len = strlen(str);
|
||||
size_t delim_len = strlen(delim);
|
||||
|
||||
for (size_t i = 0; i < str_len; ++i) {
|
||||
bool is_proper_delim = false;
|
||||
|
||||
for (size_t j = 0; j < delim_len; ++j) {
|
||||
if (str[i] == delim[j]) {
|
||||
// Skip beginning delimiters
|
||||
if (token_end - token_start == 0) {
|
||||
++token_start;
|
||||
break;
|
||||
}
|
||||
|
||||
is_proper_delim = true;
|
||||
}
|
||||
}
|
||||
|
||||
++token_end;
|
||||
if (is_proper_delim && token_end > 0) {
|
||||
--token_end;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (str[token_start] == '\0')
|
||||
return nullptr;
|
||||
|
||||
if (token_end == 0) {
|
||||
*saved_str = nullptr;
|
||||
return &str[token_start];
|
||||
}
|
||||
|
||||
if (str[token_end] == '\0')
|
||||
*saved_str = &str[token_end];
|
||||
else
|
||||
*saved_str = &str[token_end + 1];
|
||||
|
||||
str[token_end] = '\0';
|
||||
return &str[token_start];
|
||||
}
|
||||
|
||||
char* strtok(char* str, const char* delim)
|
||||
{
|
||||
static char* saved_str;
|
||||
return strtok_r(str, delim, &saved_str);
|
||||
}
|
||||
|
||||
int strcoll(const char* s1, const char* s2)
|
||||
{
|
||||
return strcmp(s1, s2);
|
||||
}
|
||||
|
||||
size_t strxfrm(char* dest, const char* src, size_t n)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < n && src[i] != '\0'; ++i)
|
||||
dest[i] = src[i];
|
||||
for (; i < n; ++i)
|
||||
dest[i] = '\0';
|
||||
return i;
|
||||
}
|
||||
|
||||
void explicit_bzero(void* ptr, size_t size)
|
||||
{
|
||||
memset(ptr, 0, size);
|
||||
asm volatile("" ::
|
||||
: "memory");
|
||||
}
|
||||
}
|
74
Userland/Libraries/LibC/string.h
Normal file
74
Userland/Libraries/LibC/string.h
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
size_t strlen(const char*);
|
||||
size_t strnlen(const char*, size_t maxlen);
|
||||
|
||||
int strcmp(const char*, const char*);
|
||||
int strncmp(const char*, const char*, size_t);
|
||||
|
||||
int memcmp(const void*, const void*, size_t);
|
||||
void* memcpy(void*, const void*, size_t);
|
||||
void* memmove(void*, const void*, size_t);
|
||||
void* memchr(const void*, int c, size_t);
|
||||
const void* memmem(const void* haystack, size_t, const void* needle, size_t);
|
||||
|
||||
void* memset(void*, int, size_t);
|
||||
void explicit_bzero(void*, size_t) __attribute__((nonnull(1)));
|
||||
|
||||
__attribute__((malloc)) char* strdup(const char*);
|
||||
__attribute__((malloc)) char* strndup(const char*, size_t);
|
||||
|
||||
__attribute__((deprecated("use strlcpy or String::copy_characters_to_buffer"))) char* strcpy(char* dest, const char* src);
|
||||
__attribute__((deprecated("use strlcpy or String::copy_characters_to_buffer"))) char* strncpy(char* dest, const char* src, size_t);
|
||||
__attribute__((warn_unused_result)) size_t strlcpy(char* dest, const char* src, size_t);
|
||||
|
||||
char* strchr(const char*, int c);
|
||||
char* strchrnul(const char*, int c);
|
||||
char* strstr(const char* haystack, const char* needle);
|
||||
char* strrchr(const char*, int c);
|
||||
|
||||
__attribute__((deprecated("use strncat"))) char* strcat(char* dest, const char* src);
|
||||
char* strncat(char* dest, const char* src, size_t);
|
||||
|
||||
size_t strspn(const char*, const char* accept);
|
||||
size_t strcspn(const char*, const char* reject);
|
||||
char* strerror(int errnum);
|
||||
char* strsignal(int signum);
|
||||
char* strpbrk(const char*, const char* accept);
|
||||
char* strtok_r(char* str, const char* delim, char** saved_str);
|
||||
char* strtok(char* str, const char* delim);
|
||||
int strcoll(const char* s1, const char* s2);
|
||||
size_t strxfrm(char* dest, const char* src, size_t n);
|
||||
|
||||
__END_DECLS
|
72
Userland/Libraries/LibC/strings.cpp
Normal file
72
Userland/Libraries/LibC/strings.cpp
Normal file
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
void bzero(void* dest, size_t n)
|
||||
{
|
||||
memset(dest, 0, n);
|
||||
}
|
||||
|
||||
void bcopy(const void* src, void* dest, size_t n)
|
||||
{
|
||||
memmove(dest, src, n);
|
||||
}
|
||||
|
||||
static char foldcase(char ch)
|
||||
{
|
||||
if (isalpha(ch))
|
||||
return tolower(ch);
|
||||
return ch;
|
||||
}
|
||||
|
||||
int strcasecmp(const char* s1, const char* s2)
|
||||
{
|
||||
for (; foldcase(*s1) == foldcase(*s2); ++s1, ++s2) {
|
||||
if (*s1 == 0)
|
||||
return 0;
|
||||
}
|
||||
return foldcase(*(const unsigned char*)s1) < foldcase(*(const unsigned char*)s2) ? -1 : 1;
|
||||
}
|
||||
|
||||
int strncasecmp(const char* s1, const char* s2, size_t n)
|
||||
{
|
||||
if (!n)
|
||||
return 0;
|
||||
do {
|
||||
if (foldcase(*s1) != foldcase(*s2++))
|
||||
return foldcase(*(const unsigned char*)s1) - foldcase(*(const unsigned char*)--s2);
|
||||
if (*s1++ == 0)
|
||||
break;
|
||||
} while (--n);
|
||||
return 0;
|
||||
}
|
||||
}
|
39
Userland/Libraries/LibC/strings.h
Normal file
39
Userland/Libraries/LibC/strings.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
int strcasecmp(const char*, const char*);
|
||||
int strncasecmp(const char*, const char*, size_t);
|
||||
void bzero(void*, size_t);
|
||||
void bcopy(const void*, void*, size_t);
|
||||
|
||||
__END_DECLS
|
48
Userland/Libraries/LibC/sys/arch/i386/regs.h
Normal file
48
Userland/Libraries/LibC/sys/arch/i386/regs.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Itamar S. <itamar8910@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Types.h>
|
||||
|
||||
struct [[gnu::packed]] PtraceRegisters {
|
||||
u32 eax;
|
||||
u32 ecx;
|
||||
u32 edx;
|
||||
u32 ebx;
|
||||
u32 esp;
|
||||
u32 ebp;
|
||||
u32 esi;
|
||||
u32 edi;
|
||||
u32 eip;
|
||||
u32 eflags;
|
||||
u32 cs;
|
||||
u32 ss;
|
||||
u32 ds;
|
||||
u32 es;
|
||||
u32 fs;
|
||||
u32 gs;
|
||||
};
|
54
Userland/Libraries/LibC/sys/cdefs.h
Normal file
54
Userland/Libraries/LibC/sys/cdefs.h
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define _POSIX_VERSION 200809L
|
||||
|
||||
#ifndef ALWAYS_INLINE
|
||||
# define ALWAYS_INLINE inline __attribute__((always_inline))
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
# ifndef __BEGIN_DECLS
|
||||
# define __BEGIN_DECLS extern "C" {
|
||||
# define __END_DECLS }
|
||||
# endif
|
||||
#else
|
||||
# ifndef __BEGIN_DECLS
|
||||
# define __BEGIN_DECLS
|
||||
# define __END_DECLS
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#undef __P
|
||||
#define __P(a) a
|
||||
|
||||
#define offsetof(type, member) __builtin_offsetof(type, member)
|
||||
|
||||
#ifdef __cplusplus
|
||||
//extern "C" int main(int, char**);
|
||||
#endif
|
27
Userland/Libraries/LibC/sys/file.h
Normal file
27
Userland/Libraries/LibC/sys/file.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
48
Userland/Libraries/LibC/sys/internals.h
Normal file
48
Userland/Libraries/LibC/sys/internals.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright (c) 2020, the SerenityOS developers.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
typedef void (*AtExitFunction)(void*);
|
||||
|
||||
extern void __libc_init();
|
||||
extern void __malloc_init();
|
||||
extern void __stdio_init();
|
||||
extern void _init();
|
||||
extern bool __environ_is_malloced;
|
||||
extern bool __stdio_is_initialized;
|
||||
|
||||
int __cxa_atexit(AtExitFunction exit_function, void* parameter, void* dso_handle);
|
||||
void __cxa_finalize(void* dso_handle);
|
||||
[[noreturn]] void __cxa_pure_virtual() __attribute__((weak));
|
||||
[[noreturn]] void __stack_chk_fail();
|
||||
[[noreturn]] void __stack_chk_fail_local();
|
||||
|
||||
__END_DECLS
|
36
Userland/Libraries/LibC/sys/ioctl.h
Normal file
36
Userland/Libraries/LibC/sys/ioctl.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/ioctl_numbers.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
int ioctl(int fd, unsigned request, ...);
|
||||
|
||||
__END_DECLS
|
94
Userland/Libraries/LibC/sys/ioctl_numbers.h
Normal file
94
Userland/Libraries/LibC/sys/ioctl_numbers.h
Normal file
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
struct winsize {
|
||||
unsigned short ws_row;
|
||||
unsigned short ws_col;
|
||||
unsigned short ws_xpixel;
|
||||
unsigned short ws_ypixel;
|
||||
};
|
||||
|
||||
struct FBResolution {
|
||||
unsigned pitch;
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
};
|
||||
|
||||
__END_DECLS
|
||||
|
||||
enum IOCtlNumber {
|
||||
TIOCGPGRP,
|
||||
TIOCSPGRP,
|
||||
TCGETS,
|
||||
TCSETS,
|
||||
TCSETSW,
|
||||
TCSETSF,
|
||||
TCFLSH,
|
||||
TIOCGWINSZ,
|
||||
TIOCSCTTY,
|
||||
TIOCNOTTY,
|
||||
TIOCSWINSZ,
|
||||
FB_IOCTL_GET_SIZE_IN_BYTES,
|
||||
FB_IOCTL_GET_RESOLUTION,
|
||||
FB_IOCTL_SET_RESOLUTION,
|
||||
FB_IOCTL_GET_BUFFER,
|
||||
FB_IOCTL_SET_BUFFER,
|
||||
SIOCSIFADDR,
|
||||
SIOCGIFADDR,
|
||||
SIOCGIFHWADDR,
|
||||
SIOCSIFNETMASK,
|
||||
SIOCADDRT,
|
||||
SIOCDELRT
|
||||
};
|
||||
|
||||
#define TIOCGPGRP TIOCGPGRP
|
||||
#define TIOCSPGRP TIOCSPGRP
|
||||
#define TCGETS TCGETS
|
||||
#define TCSETS TCSETS
|
||||
#define TCSETSW TCSETSW
|
||||
#define TCSETSF TCSETSF
|
||||
#define TCFLSH TCFLSH
|
||||
#define TIOCGWINSZ TIOCGWINSZ
|
||||
#define TIOCSCTTY TIOCSCTTY
|
||||
#define TIOCNOTTY TIOCNOTTY
|
||||
#define TIOCSWINSZ TIOCSWINSZ
|
||||
#define FB_IOCTL_GET_SIZE_IN_BYTES FB_IOCTL_GET_SIZE_IN_BYTES
|
||||
#define FB_IOCTL_GET_RESOLUTION FB_IOCTL_GET_RESOLUTION
|
||||
#define FB_IOCTL_SET_RESOLUTION FB_IOCTL_SET_RESOLUTION
|
||||
#define FB_IOCTL_GET_BUFFER FB_IOCTL_GET_BUFFER
|
||||
#define FB_IOCTL_SET_BUFFER FB_IOCTL_SET_BUFFER
|
||||
#define SIOCSIFADDR SIOCSIFADDR
|
||||
#define SIOCGIFADDR SIOCGIFADDR
|
||||
#define SIOCGIFHWADDR SIOCGIFHWADDR
|
||||
#define SIOCSIFNETMASK SIOCSIFNETMASK
|
||||
#define SIOCADDRT SIOCADDRT
|
||||
#define SIOCDELRT SIOCDELRT
|
29
Userland/Libraries/LibC/sys/mman.h
Normal file
29
Userland/Libraries/LibC/sys/mman.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <mman.h>
|
30
Userland/Libraries/LibC/sys/param.h
Normal file
30
Userland/Libraries/LibC/sys/param.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <endian.h>
|
||||
#include <limits.h>
|
40
Userland/Libraries/LibC/sys/prctl.cpp
Normal file
40
Userland/Libraries/LibC/sys/prctl.cpp
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <Kernel/API/Syscall.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/prctl.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
int prctl(int option, uintptr_t arg1, uintptr_t arg2)
|
||||
{
|
||||
int rc = syscall(SC_prctl, option, arg1, arg2);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
}
|
37
Userland/Libraries/LibC/sys/prctl.h
Normal file
37
Userland/Libraries/LibC/sys/prctl.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/prctl_numbers.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
int prctl(int option, uintptr_t arg1, uintptr_t arg2);
|
||||
|
||||
__END_DECLS
|
30
Userland/Libraries/LibC/sys/prctl_numbers.h
Normal file
30
Userland/Libraries/LibC/sys/prctl_numbers.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define PR_SET_DUMPABLE 1
|
||||
#define PR_GET_DUMPABLE 2
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue