mirror of
https://github.com/RGBCube/serenity
synced 2025-05-30 22:48:11 +00:00
LibC: Move realpath() to <stdlib.h>
This commit is contained in:
parent
fbcab844de
commit
196b64c0ae
4 changed files with 102 additions and 102 deletions
|
@ -18,6 +18,92 @@
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
template<typename T, T min_value, T max_value>
|
||||||
|
static inline T strtol_impl(const char* nptr, char** endptr, int base)
|
||||||
|
{
|
||||||
|
errno = 0;
|
||||||
|
|
||||||
|
if (base < 0 || base == 1 || base > 36) {
|
||||||
|
errno = EINVAL;
|
||||||
|
if (endptr)
|
||||||
|
*endptr = const_cast<char*>(nptr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* p = nptr;
|
||||||
|
while (isspace(*p))
|
||||||
|
++p;
|
||||||
|
|
||||||
|
bool is_negative = false;
|
||||||
|
if (*p == '-') {
|
||||||
|
is_negative = true;
|
||||||
|
++p;
|
||||||
|
} else {
|
||||||
|
if (*p == '+')
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (base == 0 || base == 16) {
|
||||||
|
if (base == 0)
|
||||||
|
base = 10;
|
||||||
|
if (*p == '0') {
|
||||||
|
if (*(p + 1) == 'X' || *(p + 1) == 'x') {
|
||||||
|
p += 2;
|
||||||
|
base = 16;
|
||||||
|
} else if (base != 16) {
|
||||||
|
base = 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
long cutoff_point = is_negative ? (min_value / base) : (max_value / base);
|
||||||
|
int max_valid_digit_at_cutoff_point = is_negative ? (min_value % base) : (max_value % base);
|
||||||
|
|
||||||
|
long num = 0;
|
||||||
|
|
||||||
|
bool has_overflowed = false;
|
||||||
|
unsigned digits_consumed = 0;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
char ch = *(p++);
|
||||||
|
int digit;
|
||||||
|
if (isdigit(ch))
|
||||||
|
digit = ch - '0';
|
||||||
|
else if (islower(ch))
|
||||||
|
digit = ch - ('a' - 10);
|
||||||
|
else if (isupper(ch))
|
||||||
|
digit = ch - ('A' - 10);
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (digit >= base)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (has_overflowed)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
bool is_past_cutoff = is_negative ? num < cutoff_point : num > cutoff_point;
|
||||||
|
|
||||||
|
if (is_past_cutoff || (num == cutoff_point && digit > max_valid_digit_at_cutoff_point)) {
|
||||||
|
has_overflowed = true;
|
||||||
|
num = is_negative ? min_value : max_value;
|
||||||
|
errno = ERANGE;
|
||||||
|
} else {
|
||||||
|
num *= base;
|
||||||
|
num += is_negative ? -digit : digit;
|
||||||
|
++digits_consumed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (endptr) {
|
||||||
|
if (has_overflowed || digits_consumed > 0)
|
||||||
|
*endptr = const_cast<char*>(p - 1);
|
||||||
|
else
|
||||||
|
*endptr = const_cast<char*>(nptr);
|
||||||
|
}
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
typedef void (*__atexit_handler)();
|
typedef void (*__atexit_handler)();
|
||||||
|
@ -167,7 +253,6 @@ int putenv(char* new_var)
|
||||||
environ = new_environ;
|
environ = new_environ;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
double strtod(const char* str, char** endptr)
|
double strtod(const char* str, char** endptr)
|
||||||
{
|
{
|
||||||
|
@ -503,92 +588,6 @@ size_t wcstombs(char* dest, const wchar_t* src, size_t max)
|
||||||
return max;
|
return max;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, T min_value, T max_value>
|
|
||||||
static T strtol_impl(const char* nptr, char** endptr, int base)
|
|
||||||
{
|
|
||||||
errno = 0;
|
|
||||||
|
|
||||||
if (base < 0 || base == 1 || base > 36) {
|
|
||||||
errno = EINVAL;
|
|
||||||
if (endptr)
|
|
||||||
*endptr = const_cast<char*>(nptr);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* p = nptr;
|
|
||||||
while (isspace(*p))
|
|
||||||
++p;
|
|
||||||
|
|
||||||
bool is_negative = false;
|
|
||||||
if (*p == '-') {
|
|
||||||
is_negative = true;
|
|
||||||
++p;
|
|
||||||
} else {
|
|
||||||
if (*p == '+')
|
|
||||||
++p;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (base == 0 || base == 16) {
|
|
||||||
if (base == 0)
|
|
||||||
base = 10;
|
|
||||||
if (*p == '0') {
|
|
||||||
if (*(p + 1) == 'X' || *(p + 1) == 'x') {
|
|
||||||
p += 2;
|
|
||||||
base = 16;
|
|
||||||
} else if (base != 16) {
|
|
||||||
base = 8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
long cutoff_point = is_negative ? (min_value / base) : (max_value / base);
|
|
||||||
int max_valid_digit_at_cutoff_point = is_negative ? (min_value % base) : (max_value % base);
|
|
||||||
|
|
||||||
long num = 0;
|
|
||||||
|
|
||||||
bool has_overflowed = false;
|
|
||||||
unsigned digits_consumed = 0;
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
char ch = *(p++);
|
|
||||||
int digit;
|
|
||||||
if (isdigit(ch))
|
|
||||||
digit = ch - '0';
|
|
||||||
else if (islower(ch))
|
|
||||||
digit = ch - ('a' - 10);
|
|
||||||
else if (isupper(ch))
|
|
||||||
digit = ch - ('A' - 10);
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (digit >= base)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (has_overflowed)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
bool is_past_cutoff = is_negative ? num < cutoff_point : num > cutoff_point;
|
|
||||||
|
|
||||||
if (is_past_cutoff || (num == cutoff_point && digit > max_valid_digit_at_cutoff_point)) {
|
|
||||||
has_overflowed = true;
|
|
||||||
num = is_negative ? min_value : max_value;
|
|
||||||
errno = ERANGE;
|
|
||||||
} else {
|
|
||||||
num *= base;
|
|
||||||
num += is_negative ? -digit : digit;
|
|
||||||
++digits_consumed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (endptr) {
|
|
||||||
if (has_overflowed || digits_consumed > 0)
|
|
||||||
*endptr = const_cast<char*>(p - 1);
|
|
||||||
else
|
|
||||||
*endptr = const_cast<char*>(nptr);
|
|
||||||
}
|
|
||||||
return num;
|
|
||||||
}
|
|
||||||
|
|
||||||
long strtol(const char* str, char** endptr, int base)
|
long strtol(const char* str, char** endptr, int base)
|
||||||
{
|
{
|
||||||
return strtol_impl<long, LONG_MIN, LONG_MAX>(str, endptr, base);
|
return strtol_impl<long, LONG_MIN, LONG_MAX>(str, endptr, base);
|
||||||
|
@ -636,3 +635,18 @@ uint32_t arc4random_uniform(uint32_t max_bounds)
|
||||||
// called "modulo bias".
|
// called "modulo bias".
|
||||||
return arc4random() % max_bounds;
|
return arc4random() % max_bounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char* realpath(const char* pathname, char* buffer)
|
||||||
|
{
|
||||||
|
size_t size = PATH_MAX;
|
||||||
|
if (buffer == nullptr)
|
||||||
|
buffer = (char*)malloc(size);
|
||||||
|
int rc = syscall(SC_realpath, pathname, buffer, size);
|
||||||
|
if (rc < 0) {
|
||||||
|
errno = -rc;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
errno = 0;
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -48,6 +48,7 @@ size_t mbstowcs(wchar_t*, const char*, size_t);
|
||||||
size_t mbtowc(wchar_t*, const char*, size_t);
|
size_t mbtowc(wchar_t*, const char*, size_t);
|
||||||
int wctomb(char*, wchar_t);
|
int wctomb(char*, wchar_t);
|
||||||
size_t wcstombs(char*, const wchar_t*, size_t);
|
size_t wcstombs(char*, const wchar_t*, size_t);
|
||||||
|
char* realpath(const char* pathname, char* buffer);
|
||||||
|
|
||||||
#define RAND_MAX 32767
|
#define RAND_MAX 32767
|
||||||
int rand();
|
int rand();
|
||||||
|
|
|
@ -578,20 +578,6 @@ int umount(const char* mountpoint)
|
||||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
char* realpath(const char* pathname, char* buffer)
|
|
||||||
{
|
|
||||||
size_t size = PATH_MAX;
|
|
||||||
if (buffer == nullptr)
|
|
||||||
buffer = (char*)malloc(size);
|
|
||||||
int rc = syscall(SC_realpath, pathname, buffer, size);
|
|
||||||
if (rc < 0) {
|
|
||||||
errno = -rc;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
errno = 0;
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
void dump_backtrace()
|
void dump_backtrace()
|
||||||
{
|
{
|
||||||
syscall(SC_dump_backtrace);
|
syscall(SC_dump_backtrace);
|
||||||
|
|
|
@ -115,7 +115,6 @@ int halt();
|
||||||
int reboot();
|
int reboot();
|
||||||
int mount(const char* device, const char* mountpoint, const char* fstype);
|
int mount(const char* device, const char* mountpoint, const char* fstype);
|
||||||
int umount(const char* mountpoint);
|
int umount(const char* mountpoint);
|
||||||
char* realpath(const char* pathname, char* buffer);
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
_PC_NAME_MAX,
|
_PC_NAME_MAX,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue