diff --git a/lib/std/core/env.c3 b/lib/std/core/env.c3 index 6a5d7d8b9..32748c8b2 100644 --- a/lib/std/core/env.c3 +++ b/lib/std/core/env.c3 @@ -63,3 +63,27 @@ const usz LLVM_VERSION = $$LLVM_VERSION; const bool BENCHMARKING = $$BENCHMARKING; const bool TESTING = $$TESTING; const usz TEMP_ALLOCATOR_SIZE = 128 * 1024; + +macro bool os_is_posix() +{ + $switch (OS_TYPE): + $case IOS: + $case MACOSX: + $case NETBSD: + $case LINUX: + $case KFREEBSD: + $case FREEBSD: + $case OPENBSD: + $case SOLARIS: + $case TVOS: + $case WATCHOS: + return true; + $case WIN32: + $case WASI: + $case EMSCRIPTEN: + return false; + $default: + $echo("Assuming non-Posix environment"); + return false; + $endswitch; +} \ No newline at end of file diff --git a/lib/std/core/os/linux.c3 b/lib/std/core/os/linux.c3 deleted file mode 100644 index 93db894d4..000000000 --- a/lib/std/core/os/linux.c3 +++ /dev/null @@ -1,17 +0,0 @@ -module std::core::os::linux; - -$if (env::OS_TYPE == OsType.LINUX): - -extern fn int* __errno_location(); - -fn int errno() @inline -{ - return *__errno_location(); -} - -fn void errno_set(int err) -{ - *(__errno_location()) = err; -} - -$endif; diff --git a/lib/std/core/os/macos.c3 b/lib/std/core/os/macos.c3 deleted file mode 100644 index b1f672dc1..000000000 --- a/lib/std/core/os/macos.c3 +++ /dev/null @@ -1,14 +0,0 @@ -module std::core::os::macos; -$if (env::OS_TYPE == OsType.MACOSX): - -extern fn int* __error(); - -fn int errno() @inline -{ - return *__error(); -} -fn void errno_set(int err) -{ - *(__error()) = err; -} -$endif; diff --git a/lib/std/core/os/windows.c3 b/lib/std/core/os/windows.c3 deleted file mode 100644 index 0a89ba7c4..000000000 --- a/lib/std/core/os/windows.c3 +++ /dev/null @@ -1,10 +0,0 @@ -module std::core::os::windows; - -$if (env::OS_TYPE == OsType.WIN32): - -extern fn int getLastError() @stdcall @extname("GetLastError"); -fn int errno() @inline -{ - return getLastError(); -} -$endif; diff --git a/lib/std/io/io.c3 b/lib/std/io/io.c3 index 4ca624869..3543d0f23 100644 --- a/lib/std/io/io.c3 +++ b/lib/std/io/io.c3 @@ -9,6 +9,30 @@ struct File CFile file; } +enum Seek +{ + SET, + CURSOR, + END +} + +fault IoError +{ + FILE_NOT_FOUND, + FILE_NOT_SEEKABLE, + FILE_NOT_VALID, + FILE_INVALID_POSITION, + FILE_OVERFLOW, + FILE_IS_PIPE, + FILE_EOF, + FILE_INCOMPLETE_WRITE, + FILE_NOT_DIR, + NO_PERMISSION, + NAME_TOO_LONG, + INTERRUPTED, + GENERAL_ERROR, + UNKNOWN_ERROR, +} fn int putchar(char c) @inline { @@ -39,181 +63,8 @@ fn int println(char *message = "") @inline return libc::puts(message); } -fn void! File.open(File* file, char[] filename, char[] mode) -{ - @pool() - { - char* filename_copy = tmalloc(filename.len + 1); - char* mode_copy = tmalloc(mode.len + 1); - mem::copy(filename_copy, (char*)(filename), filename.len); - mem::copy(mode_copy, (char*)(mode), mode.len); - filename_copy[filename.len] = 0; - mode_copy[filename.len] = 0; - file.file = libc::fopen(filename_copy, mode_copy); - if (!file.file) return IoError.FILE_NOT_FOUND!; - }; -} -enum Seek -{ - SET, - CURSOR, - END -} - -fault IoError -{ - FILE_NOT_FOUND, - FILE_NOT_SEEKABLE, - FILE_NOT_VALID, - FILE_INVALID_POSITION, - FILE_OVERFLOW, - FILE_IS_PIPE, - FILE_EOF, - FILE_INCOMPLETE_WRITE, - INTERRUPTED, - UNKNOWN_ERROR, -} - -/** - * @require file.file != null - **/ -fn void! File.seek(File *file, long offset, Seek seekMode = Seek.SET) -{ - if (libc::fseek(file.file, (SeekIndex)(offset), (int)(seekMode))) - { - switch (libc::errno()) - { - case errno::EBADF: return IoError.FILE_NOT_SEEKABLE!; - case errno::EINVAL: return IoError.FILE_INVALID_POSITION!; - case errno::EOVERFLOW: return IoError.FILE_OVERFLOW!; - case errno::ESPIPE: return IoError.FILE_IS_PIPE!; - default: return IoError.UNKNOWN_ERROR!; - } - } -} - -/** - * @require file && file.file != null - */ -fn void! File.putc(File *file, char c) -{ - if (!libc::fputc(c, file.file)) return IoError.FILE_EOF!; -} - -/** - * @require file != null - */ -fn void! File.close(File *file) @inline -{ - if (file.file && libc::fclose(file.file)) - { - switch (libc::errno()) - { - case errno::ECONNRESET: - case errno::EBADF: return IoError.FILE_NOT_VALID!; - case errno::EINTR: return IoError.INTERRUPTED!; - case errno::EDQUOT: - case errno::EFAULT: - case errno::EAGAIN: - case errno::EFBIG: - case errno::ENETDOWN: - case errno::ENETUNREACH: - case errno::ENOSPC: - case errno::EIO: return IoError.FILE_INCOMPLETE_WRITE!; - default: return IoError.UNKNOWN_ERROR!; - } - } - file.file = null; -} - -/** - * @require file && file.file - */ -fn bool File.eof(File* file) @inline -{ - return libc::feof(file.file) != 0; -} - -/** - * @require file && file.file - */ -fn usz File.read(File* file, void* buffer, usz items, usz element_size = 1) -{ - return libc::fread(buffer, element_size, items, file.file); -} - -/** - * @param [&in] file - * @param [&out] buffer - * @param items - * @param element_size - * @require file.file `File must be initialized` - * @require element_size > 1 - */ -fn usz File.write(File* file, void* buffer, usz items, usz element_size = 1) -{ - return libc::fwrite(buffer, element_size, items, file.file); -} - -/** - * @param [&in] file - * @require file.file `File must be initialized` - */ -fn usz! File.println(File* file, char[] string) -{ - usz len = string.len; - if (len != libc::fwrite(string.ptr, 1, len, file.file)) return IoError.UNKNOWN_ERROR!; - if (!libc::putc('\n', file.file)) return IoError.UNKNOWN_ERROR!; - return len + 1; -} - -/** - * @param [&in] file - * @require file.file `File must be initialized` - */ -fn String File.getline(File* file, Allocator* allocator = mem::current_allocator()) -{ - String s = string::new_with_capacity(120, allocator); - while (!file.eof()) - { - int c = libc::fgetc(file.file); - if (c == -1) break; - if (c == '\n') break; - s.append_char((char)c); - } - return s; -} - -/** - * @param [&in] file - * @require file.file `File must be initialized` - * @return "a zero terminated char[] (the pointer may be safely cast into a ZString)" - */ -fn char[] File.tgetline(File* file) -{ - - String s = file.getline(mem::temp_allocator()); - ZString z = s.zstr(); - return z[:s.len()]; -} - -fn char! File.getc(File* file) -{ - int c = libc::fgetc(file.file); - if (c == -1) return IoError.FILE_EOF!; - return (char)c; -} - -/** - * @param [&in] file - * @require file.file `File must be initialized` - */ -fn void File.flush(File* file) -{ - libc::fflush(file.file); -} fn File stdout() { diff --git a/lib/std/io/io_file.c3 b/lib/std/io/io_file.c3 new file mode 100644 index 000000000..0390404e1 --- /dev/null +++ b/lib/std/io/io_file.c3 @@ -0,0 +1,157 @@ +module std::io; +import libc; + +fn void! File.open(File* file, char[] filename, char[] mode) +{ + @pool() + { + char* filename_copy = tmalloc(filename.len + 1); + char* mode_copy = tmalloc(mode.len + 1); + + mem::copy(filename_copy, (char*)(filename), filename.len); + mem::copy(mode_copy, (char*)(mode), mode.len); + filename_copy[filename.len] = 0; + mode_copy[filename.len] = 0; + file.file = libc::fopen(filename_copy, mode_copy); + if (!file.file) return IoError.FILE_NOT_FOUND!; + }; +} + +/** + * @require file.file != null + **/ +fn void! File.seek(File *file, long offset, Seek seekMode = Seek.SET) +{ + if (libc::fseek(file.file, (SeekIndex)(offset), (int)(seekMode))) + { + switch (libc::errno()) + { + case errno::EBADF: return IoError.FILE_NOT_SEEKABLE!; + case errno::EINVAL: return IoError.FILE_INVALID_POSITION!; + case errno::EOVERFLOW: return IoError.FILE_OVERFLOW!; + case errno::ESPIPE: return IoError.FILE_IS_PIPE!; + default: return IoError.UNKNOWN_ERROR!; + } + } +} + +/** + * @require file && file.file != null + */ +fn void! File.putc(File *file, char c) +{ + if (!libc::fputc(c, file.file)) return IoError.FILE_EOF!; +} + +/** + * @require file != null + */ +fn void! File.close(File *file) @inline +{ + if (file.file && libc::fclose(file.file)) + { + switch (libc::errno()) + { + case errno::ECONNRESET: + case errno::EBADF: return IoError.FILE_NOT_VALID!; + case errno::EINTR: return IoError.INTERRUPTED!; + case errno::EDQUOT: + case errno::EFAULT: + case errno::EAGAIN: + case errno::EFBIG: + case errno::ENETDOWN: + case errno::ENETUNREACH: + case errno::ENOSPC: + case errno::EIO: return IoError.FILE_INCOMPLETE_WRITE!; + default: return IoError.UNKNOWN_ERROR!; + } + } + file.file = null; +} + +/** + * @require file && file.file + */ +fn bool File.eof(File* file) @inline +{ + return libc::feof(file.file) != 0; +} + +/** + * @require file && file.file + */ +fn usz File.read(File* file, void* buffer, usz items, usz element_size = 1) +{ + return libc::fread(buffer, element_size, items, file.file); +} + +/** + * @param [&in] file + * @param [&out] buffer + * @param items + * @param element_size + * @require file.file `File must be initialized` + * @require element_size > 1 + */ +fn usz File.write(File* file, void* buffer, usz items, usz element_size = 1) +{ + return libc::fwrite(buffer, element_size, items, file.file); +} + +/** + * @param [&in] file + * @require file.file `File must be initialized` + */ +fn usz! File.println(File* file, char[] string) +{ + usz len = string.len; + if (len != libc::fwrite(string.ptr, 1, len, file.file)) return IoError.UNKNOWN_ERROR!; + if (!libc::putc('\n', file.file)) return IoError.UNKNOWN_ERROR!; + return len + 1; +} + +/** + * @param [&in] file + * @require file.file `File must be initialized` + */ +fn String File.getline(File* file, Allocator* allocator = mem::current_allocator()) +{ + String s = string::new_with_capacity(120, allocator); + while (!file.eof()) + { + int c = libc::fgetc(file.file); + if (c == -1) break; + if (c == '\n') break; + s.append_char((char)c); + } + return s; +} + +/** + * @param [&in] file + * @require file.file `File must be initialized` + * @return "a zero terminated char[] (the pointer may be safely cast into a ZString)" + */ +fn char[] File.tgetline(File* file) +{ + + String s = file.getline(mem::temp_allocator()); + ZString z = s.zstr(); + return z[:s.len()]; +} + +fn char! File.getc(File* file) +{ + int c = libc::fgetc(file.file); + if (c == -1) return IoError.FILE_EOF!; + return (char)c; +} + +/** + * @param [&in] file + * @require file.file `File must be initialized` + */ +fn void File.flush(File* file) +{ + libc::fflush(file.file); +} diff --git a/lib/std/io/io_fileinfo.c3 b/lib/std/io/io_fileinfo.c3 new file mode 100644 index 000000000..644eeaf7a --- /dev/null +++ b/lib/std/io/io_fileinfo.c3 @@ -0,0 +1,81 @@ +module std::io::file; +import libc; + +struct FileInfo +{ + ulong size; +} + +$switch (env::OS_TYPE): +$case MACOSX: +$case IOS: +$case WATCHOS: +$case TVOS: +private struct DarwinTimespec +{ + long tv_sec; + long tv_nsec; +} +private struct Darwin64Stat +{ + int st_dev; + ushort st_mode; + ushort st_nlink; + ulong st_ino; + uint st_uid; + uint st_gid; + int st_rdev; + DarwinTimespec st_atimespec; // time of last access + DarwinTimespec st_mtimespec; // time of last data modification + DarwinTimespec st_ctimespec; // time of last status change + DarwinTimespec st_birthtimespec; // time of file creation(birth) + long st_size; + long st_blocks; + int st_blocksize; + uint st_flags; + uint st_gen; + int st_lspare; + long[2] st_qspare; +} +extern fn int _stat(ZString str, Darwin64Stat* stat) @extname("stat64"); +fn void! FileInfo.read(FileInfo* info, Path path) +{ + @pool() + { + Darwin64Stat stat; + int res = _stat(str::tcopy_zstring((char[])path), &stat); + if (res != 0) + { + switch (libc::errno()) + { + case errno::EBADF: + return IoError.FILE_NOT_VALID!; + case errno::EFAULT: + unreachable("Invalid stat"); + case errno::EIO: + return IoError.GENERAL_ERROR!; + case errno::EACCES: + return IoError.NO_PERMISSION!; + case errno::ELOOP: + return IoError.NO_PERMISSION!; + case errno::ENAMETOOLONG: + return IoError.NAME_TOO_LONG!; + case errno::ENOENT: + return IoError.FILE_NOT_FOUND!; + case errno::ENOTDIR: + return IoError.FILE_NOT_DIR!; + case errno::EOVERFLOW: + return IoError.GENERAL_ERROR!; + default: + return IoError.UNKNOWN_ERROR!; + } + } + info.size = stat.st_size; + }; +} +$default: +macro void! FileInfo.read(FileInfo* info, Path path) +{ + $assert("Unsupported function"); +} +$endswitch; \ No newline at end of file diff --git a/lib/std/libc.c3 b/lib/std/libc/libc.c3 similarity index 74% rename from lib/std/libc.c3 rename to lib/std/libc/libc.c3 index d6e91a6e9..569808377 100644 --- a/lib/std/libc.c3 +++ b/lib/std/libc/libc.c3 @@ -28,17 +28,13 @@ struct LongDivResult fn Errno errno() { - $if (env::OS_TYPE == OsType.WIN32): - return (Errno)windows::errno(); - $elif (env::OS_TYPE == OsType.MACOSX): - return (Errno)macos::errno(); - $elif (env::OS_TYPE == OsType.LINUX): - return (Errno)linux::errno(); - $else: - return errno::ENOTRECOVERABLE; - $endif; + return (Errno)os::errno(); } +fn void errno_set(Errno e) +{ + os::errno_set((int)e); +} define TerminateFunction = fn void(); define CompareFunction = fn int(void*, void*); @@ -247,46 +243,84 @@ extern fn SignalFunction signal(int sig, SignalFunction function); module libc::errno; -const Errno EPERM = 1; /* Operation not permitted */ -const Errno ENOENT = 2; /* No such file or directory */ -const Errno ESRCH = 3; /* No such process */ -const Errno EINTR = 4; /* Interrupted system call */ -const Errno EIO = 5; /* I/O error */ -const Errno ENXIO = 6; /* No such device or address */ -const Errno E2BIG = 7; /* Argument list too long */ -const Errno ENOEXEC = 8; /* Exec format error */ -const Errno EBADF = 9; /* Bad file number */ -const Errno ECHILD = 10; /* No child processes */ -const Errno EAGAIN = 11; /* Try again */ -const Errno ENOMEM = 12; /* Out of memory */ -const Errno EACCES = 13; /* Permission denied */ -const Errno EFAULT = 14; /* Bad address */ -const Errno ENOTBLK = 15; /* Block device required */ -const Errno EBUSY = 16; /* Device or resource busy */ -const Errno EEXIST = 17; /* File exists */ -const Errno EXDEV = 18; /* Cross-device link */ -const Errno ENODEV = 19; /* No such device */ -const Errno ENOTDIR = 20; /* Not a directory */ -const Errno EISDIR = 21; /* Is a directory */ -const Errno EINVAL = 22; /* Invalid argument */ -const Errno ENFILE = 23; /* File table overflow */ -const Errno EMFILE = 24; /* Too many open files */ -const Errno ENOTTY = 25; /* Not a typewriter */ -const Errno ETXTBSY = 26; /* Text file busy */ -const Errno EFBIG = 27; /* File too large */ -const Errno ENOSPC = 28; /* No space left on device */ -const Errno ESPIPE = 29; /* Illegal seek */ -const Errno EROFS = 30; /* Read-only file system */ -const Errno EMLINK = 31; /* Too many links */ -const Errno EPIPE = 32; /* Broken pipe */ -const Errno EDOM = 33; /* Math argument out of domain of func */ -const Errno ERANGE = 34; /* Math result not representable */ -const Errno EDEADLK = 35; /* Resource deadlock would occur */ -const Errno ENAMETOOLONG = 36; /* File name too long */ +const Errno EPERM = 1; // Operation not permitted +const Errno ENOENT = 2; // No such file or directory +const Errno ESRCH = 3; // No such process +const Errno EINTR = 4; // Interrupted system call +const Errno EIO = 5; // I/O error +const Errno ENXIO = 6; // No such device or address +const Errno E2BIG = 7; // Argument list too long +const Errno ENOEXEC = 8; // Exec format error +const Errno EBADF = 9; // Bad file number +const Errno ECHILD = 10; // No child processes + +$if (env::OS_TYPE == OsType.MACOSX): +const Errno EAGAIN = 35; // Try again Macos +$else: +const Errno EAGAIN = 11; // Try again +$endif; + +const Errno ENOMEM = 12; // Out of memory +const Errno EACCES = 13; // Permission denied +const Errno EFAULT = 14; // Bad address +const Errno ENOTBLK = 15; // Block device required, not on Win32 +const Errno EBUSY = 16; // Device or resource busy +const Errno EEXIST = 17; // File exists +const Errno EXDEV = 18; // Cross-device link +const Errno ENODEV = 19; // No such device +const Errno ENOTDIR = 20; // Not a directory +const Errno EISDIR = 21; // Is a directory +const Errno EINVAL = 22; // Invalid argument +const Errno ENFILE = 23; // File table overflow +const Errno EMFILE = 24; // Too many open files +const Errno ENOTTY = 25; // Not a typewriter +const Errno ETXTBSY = 26; // Text file busy, not on Win32 +const Errno EFBIG = 27; // File too large +const Errno ENOSPC = 28; // No space left on device +const Errno ESPIPE = 29; // Illegal seek +const Errno EROFS = 30; // Read-only file system +const Errno EMLINK = 31; // Too many links +const Errno EPIPE = 32; // Broken pipe +const Errno EDOM = 33; // Math argument out of domain of func +const Errno ERANGE = 34; // Math result not representable + +$if (env::OS_TYPE == OsType.MACOSX): +const Errno EDEADLK = 11; // Resource deadlock would occur MacOS +const Errno ENAMETOOLONG = 63; // File name too long MacOS +const Errno ELOOP = 62; // Too many symbolic links encountered +const Errno EOVERFLOW = 84; // Value too large for defined data type Macos +const Errno ECONNRESET = 54; // Connection reset by peer Macos +const Errno ENETDOWN = 50; // Network is down MacOS +const Errno ENETUNREACH = 51; // Network is unreachable MacOS +const Errno ENETRESET = 52; // Network dropped connection because of reset MacOS + +$elif (env::OS_TYPE == OsType.WIN32): +const Errno EDEADLK = 36; // Resource deadlock would occur Win32 +const Errno ENAMETOOLONG = 38; // File name too long Win32 +const Errno ELOOP = 114; // Too many symbolic links encountered +const Errno EOVERFLOW = 132; // Value too large for defined data type +const Errno ENETDOWN = 116; // Network is down +const Errno ECONNRESET = 108; // Connection reset by peer +const Errno ENETUNREACH = 118; // Network is unreachable +const Errno ENETRESET = 117; // Network dropped connection because of reset + +$else: +const Errno EDEADLK = 35; // Resource deadlock would occur Linux (others?) +const Errno ENAMETOOLONG = 36; // File name too long Linux (others?) +const Errno ELOOP = 40; // Too many symbolic links encountered +const Errno EOVERFLOW = 75; // Value too large for defined data type +const Errno ENETDOWN = 100; // Network is down +const Errno ECONNRESET = 104; // Connection reset by peer +const Errno ENETUNREACH = 101; // Network is unreachable +const Errno ENETRESET = 102; // Network dropped connection because of reset + +$endif; + + +/* const Errno ENOLCK = 37; /* No record locks available */ const Errno ENOSYS = 38; /* Function not implemented */ const Errno ENOTEMPTY = 39; /* Directory not empty */ -const Errno ELOOP = 40; /* Too many symbolic links encountered */ const Errno ENOMSG = 42; /* No message of desired type */ const Errno EIDRM = 43; /* Identifier removed */ @@ -321,7 +355,6 @@ const Errno EPROTO = 71; /* Protocol error */ const Errno EMULTIHOP = 72; /* Multihop attempted */ const Errno EDOTDOT = 73; /* RFS specific error */ const Errno EBADMSG = 74; /* Not a data message */ -const Errno EOVERFLOW = 75; /* Value too large for defined data type */ const Errno ENOTUNIQ = 76; /* Name not unique on network */ const Errno EBADFD = 77; /* File descriptor in bad state */ const Errno EREMCHG = 78; /* Remote address changed */ @@ -346,11 +379,7 @@ const Errno EPFNOSUPPORT = 96; /* Protocol family not supported */ const Errno EAFNOSUPPORT = 97; /* Address family not supported by protocol */ const Errno EADDRINUSE = 98; /* Address already in use */ const Errno EADDRNOTAVAIL = 99; /* Cannot assign requested address */ -const Errno ENETDOWN = 100; /* Network is down */ -const Errno ENETUNREACH = 101; /* Network is unreachable */ -const Errno ENETRESET = 102; /* Network dropped connection because of reset */ const Errno ECONNABORTED = 103; /* Software caused connection abort */ -const Errno ECONNRESET = 104; /* Connection reset by peer */ const Errno ENOBUFS = 105; /* No buffer space available */ const Errno EISCONN = 106; /* Transport endpoint is already connected */ const Errno ENOTCONN = 107; /* Transport endpoint is not connected */ @@ -360,15 +389,30 @@ const Errno ETIMEDOUT = 110; /* Connection timed out */ const Errno ECONNREFUSED = 111; /* Connection refused */ const Errno EHOSTDOWN = 112; /* Host is down */ const Errno EHOSTUNREACH = 113; /* No route to host */ -const Errno EALREADY = 114; /* Operation already in progress */ -const Errno EINPROGRESS = 115; /* Operation now in progress */ +*/ +$if (env::OS_TYPE == OsType.MACOSX): +const Errno EINPROGRESS = 36; // Operation now in progress MacOS +const Errno EALREADY = 37; // Operation already in progress MacOS +const Errno EDQUOT = 69; // Quota exceeded, MacOS + +$elif (env::OS_TYPE == OsType.WIN32): +const Errno EALREADY = 103; // Operation already in progress +const Errno EINPROGRESS = 112; // Operation now in progress Win32 +const Errno EDQUOT = -122; // Quota exceeded, not in Win32 + +$else: +const Errno EALREADY = 114; // Operation already in progress +const Errno EINPROGRESS = 115; // Operation now in progress +const Errno EDQUOT = 122; // Quota exceeded +$endif; + +/* const Errno ESTALE = 116; /* Stale NFS file handle */ const Errno EUCLEAN = 117; /* Structure needs cleaning */ const Errno ENOTNAM = 118; /* Not a XENIX named type file */ const Errno ENAVAIL = 119; /* No XENIX semaphores available */ const Errno EISNAM = 120; /* Is a named type file */ const Errno EREMOTEIO = 121; /* Remote I/O error */ -const Errno EDQUOT = 122; /* Quota exceeded */ const Errno ENOMEDIUM = 123; /* No medium found */ const Errno EMEDIUMTYPE = 124; /* Wrong medium type */ @@ -380,5 +424,5 @@ const Errno EKEYREJECTED = 129; /* Key was rejected by service */ const Errno EOWNERDEAD = 130; /* Owner died */ const Errno ENOTRECOVERABLE = 131; /* State not recoverable */ - +*/ diff --git a/lib/std/libc/os/errno.c3 b/lib/std/libc/os/errno.c3 new file mode 100644 index 000000000..2ffcb675a --- /dev/null +++ b/lib/std/libc/os/errno.c3 @@ -0,0 +1,37 @@ +module libc::os; + +$switch (env::OS_TYPE): + +$case LINUX: + +extern fn int* __errno_location(); + +macro int errno() = *__errno_location(); +macro void errno_set(int err) = *(__errno_location()) = err; + +$case MACOSX: + +extern fn int* __error(); +macro int errno() = *__error(); +macro void errno_set(int err) = *(__error()) = err; + +$case WIN32: + +macro int errno() +{ + int holder; + _get_errno(&holder); + return holder; +} + +macro void errno_set(int err) = _set_errno(err); + +extern fn void _get_errno(int* result); +extern fn void _set_errno(int err); + +$default: + +macro int errno() = 1; +fn void errno_set(int err) {} + +$endswitch; diff --git a/src/utils/file_utils.c b/src/utils/file_utils.c index 55a2c91ca..4bb5cc686 100644 --- a/src/utils/file_utils.c +++ b/src/utils/file_utils.c @@ -246,7 +246,7 @@ static inline const char *lib_find(const char *exe_path, const char *rel_path) if (err || !S_ISDIR(info.st_mode)) return NULL; DEBUG_LOG("Potential lib found, sanity check for libc..."); - scratch_buffer_append("/libc.c3"); + scratch_buffer_append("/libc/libc.c3"); err = stat(scratch_buffer_to_string(), &info); if (err || !S_ISREG(info.st_mode)) return NULL; diff --git a/src/utils/taskqueue.c b/src/utils/taskqueue.c index 5d6e39660..2563d0a1c 100644 --- a/src/utils/taskqueue.c +++ b/src/utils/taskqueue.c @@ -9,12 +9,12 @@ typedef struct TaskQueue_ { pthread_t *threads; - int thread_count; + volatile int thread_count; pthread_mutex_t lock; pthread_cond_t notify; - Task **queue; - bool shutdown; - int active_threads; + volatile Task **queue; + volatile bool shutdown; + volatile int active_threads; } TaskQueue; static void *taskqueue_thread(void *queue) @@ -36,7 +36,7 @@ static void *taskqueue_thread(void *queue) } if (task_queue->shutdown) break; - Task *task = task_queue->queue[vec_size(task_queue->queue) - 1]; + Task *task = (Task*)task_queue->queue[vec_size(task_queue->queue) - 1]; vec_pop(task_queue->queue); task_queue->active_threads++; was_active = true;