mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Some work on io libs.
This commit is contained in:
committed by
Christoffer Lerno
parent
2a4d43d7c7
commit
af0174f360
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
197
lib/std/io/io.c3
197
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()
|
||||
{
|
||||
|
||||
157
lib/std/io/io_file.c3
Normal file
157
lib/std/io/io_file.c3
Normal file
@@ -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);
|
||||
}
|
||||
81
lib/std/io/io_fileinfo.c3
Normal file
81
lib/std/io/io_fileinfo.c3
Normal file
@@ -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;
|
||||
@@ -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 */
|
||||
|
||||
*/
|
||||
|
||||
37
lib/std/libc/os/errno.c3
Normal file
37
lib/std/libc/os/errno.c3
Normal file
@@ -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;
|
||||
Reference in New Issue
Block a user