Compare commits
No commits in common. "82978da5e3416b5510a9bd2a44ed5899dba0de31" and "609067cefa3685ef813eb6a68f115f173f189fae" have entirely different histories.
82978da5e3
...
609067cefa
|
@ -14,7 +14,6 @@ asm_syscall_handler:
|
||||||
pushl %edi
|
pushl %edi
|
||||||
pushl %esi
|
pushl %esi
|
||||||
pushl %ebp
|
pushl %ebp
|
||||||
cld
|
|
||||||
|
|
||||||
# align stack
|
# align stack
|
||||||
movl %esp, %ebp
|
movl %esp, %ebp
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
isr_stub:
|
isr_stub:
|
||||||
push_userspace
|
push_userspace
|
||||||
load_kernel_segments
|
load_kernel_segments
|
||||||
cld
|
|
||||||
|
|
||||||
movl %cr0, %eax; pushl %eax
|
movl %cr0, %eax; pushl %eax
|
||||||
movl %cr2, %eax; pushl %eax
|
movl %cr2, %eax; pushl %eax
|
||||||
|
@ -59,7 +58,6 @@ isr_stub:
|
||||||
irq_stub:
|
irq_stub:
|
||||||
push_userspace
|
push_userspace
|
||||||
load_kernel_segments
|
load_kernel_segments
|
||||||
cld
|
|
||||||
|
|
||||||
movl 40(%esp), %eax # interrupt number
|
movl 40(%esp), %eax # interrupt number
|
||||||
|
|
||||||
|
@ -81,7 +79,6 @@ irq_stub:
|
||||||
asm_yield_handler:
|
asm_yield_handler:
|
||||||
# This can only be called from kernel, so no segment saving is needed
|
# This can only be called from kernel, so no segment saving is needed
|
||||||
pushal
|
pushal
|
||||||
cld
|
|
||||||
|
|
||||||
movl %esp, %eax # interrupt registers ptr
|
movl %esp, %eax # interrupt registers ptr
|
||||||
leal 32(%esp), %ebx # interrupt stack ptr
|
leal 32(%esp), %ebx # interrupt stack ptr
|
||||||
|
@ -104,7 +101,6 @@ asm_yield_handler:
|
||||||
asm_ipi_handler:
|
asm_ipi_handler:
|
||||||
push_userspace
|
push_userspace
|
||||||
load_kernel_segments
|
load_kernel_segments
|
||||||
cld
|
|
||||||
|
|
||||||
movl %esp, %ebp
|
movl %esp, %ebp
|
||||||
subl $15, %esp
|
subl $15, %esp
|
||||||
|
@ -122,7 +118,6 @@ asm_ipi_handler:
|
||||||
asm_timer_handler:
|
asm_timer_handler:
|
||||||
push_userspace
|
push_userspace
|
||||||
load_kernel_segments
|
load_kernel_segments
|
||||||
cld
|
|
||||||
|
|
||||||
movl %esp, %ebp
|
movl %esp, %ebp
|
||||||
subl $15, %esp
|
subl $15, %esp
|
||||||
|
|
|
@ -16,7 +16,6 @@ asm_syscall_handler:
|
||||||
pushq %r13
|
pushq %r13
|
||||||
pushq %r14
|
pushq %r14
|
||||||
pushq %r15
|
pushq %r15
|
||||||
cld
|
|
||||||
|
|
||||||
movq %rsi, %r8
|
movq %rsi, %r8
|
||||||
movq %rdi, %r9
|
movq %rdi, %r9
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
|
|
||||||
isr_stub:
|
isr_stub:
|
||||||
pushaq
|
pushaq
|
||||||
cld
|
|
||||||
movq %cr0, %rax; pushq %rax
|
movq %cr0, %rax; pushq %rax
|
||||||
movq %cr2, %rax; pushq %rax
|
movq %cr2, %rax; pushq %rax
|
||||||
movq %cr3, %rax; pushq %rax
|
movq %cr3, %rax; pushq %rax
|
||||||
|
@ -55,7 +55,6 @@ isr_stub:
|
||||||
|
|
||||||
irq_stub:
|
irq_stub:
|
||||||
pushaq
|
pushaq
|
||||||
cld
|
|
||||||
movq 120(%rsp), %rdi # irq number
|
movq 120(%rsp), %rdi # irq number
|
||||||
call cpp_irq_handler
|
call cpp_irq_handler
|
||||||
popaq
|
popaq
|
||||||
|
@ -65,7 +64,6 @@ irq_stub:
|
||||||
.global asm_yield_handler
|
.global asm_yield_handler
|
||||||
asm_yield_handler:
|
asm_yield_handler:
|
||||||
pushaq
|
pushaq
|
||||||
cld
|
|
||||||
leaq 120(%rsp), %rdi # interrupt stack ptr
|
leaq 120(%rsp), %rdi # interrupt stack ptr
|
||||||
movq %rsp, %rsi # interrupt register ptr
|
movq %rsp, %rsi # interrupt register ptr
|
||||||
call cpp_yield_handler
|
call cpp_yield_handler
|
||||||
|
@ -75,7 +73,6 @@ asm_yield_handler:
|
||||||
.global asm_ipi_handler
|
.global asm_ipi_handler
|
||||||
asm_ipi_handler:
|
asm_ipi_handler:
|
||||||
pushaq
|
pushaq
|
||||||
cld
|
|
||||||
call cpp_ipi_handler
|
call cpp_ipi_handler
|
||||||
popaq
|
popaq
|
||||||
iretq
|
iretq
|
||||||
|
@ -83,7 +80,6 @@ asm_ipi_handler:
|
||||||
.global asm_timer_handler
|
.global asm_timer_handler
|
||||||
asm_timer_handler:
|
asm_timer_handler:
|
||||||
pushaq
|
pushaq
|
||||||
cld
|
|
||||||
call cpp_timer_handler
|
call cpp_timer_handler
|
||||||
popaq
|
popaq
|
||||||
iretq
|
iretq
|
||||||
|
|
|
@ -283,14 +283,16 @@ namespace Kernel::ACPI::AML
|
||||||
switch (opcode)
|
switch (opcode)
|
||||||
{
|
{
|
||||||
case AML::Byte::PackageOp:
|
case AML::Byte::PackageOp:
|
||||||
if (context.aml_data.empty())
|
|
||||||
return BAN::Error::from_errno(ENODATA);
|
|
||||||
num_elements = context.aml_data[0];
|
num_elements = context.aml_data[0];
|
||||||
context.aml_data = context.aml_data.slice(1);
|
context.aml_data = context.aml_data.slice(1);
|
||||||
break;
|
break;
|
||||||
case AML::Byte::VarPackageOp:
|
case AML::Byte::VarPackageOp:
|
||||||
num_elements = TRY(convert_node(TRY(parse_node(context)), ConvInteger, sizeof(uint64_t))).as.integer.value;
|
{
|
||||||
|
auto node = TRY(parse_node(context));
|
||||||
|
node = TRY(convert_node(BAN::move(node), ConvInteger, sizeof(uint64_t)));
|
||||||
|
num_elements = node.as.integer.value;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
@ -1866,13 +1868,10 @@ namespace Kernel::ACPI::AML
|
||||||
ASSERT(static_cast<AML::Byte>(context.aml_data[0]) == AML::Byte::NotifyOp);
|
ASSERT(static_cast<AML::Byte>(context.aml_data[0]) == AML::Byte::NotifyOp);
|
||||||
context.aml_data = context.aml_data.slice(1);
|
context.aml_data = context.aml_data.slice(1);
|
||||||
|
|
||||||
auto [obj_path, obj_ref] = TRY(parse_super_name(context, true));
|
auto object = TRY(parse_super_name(context, true));
|
||||||
auto value = TRY(convert_node(TRY(parse_node(context)), ConvInteger, sizeof(uint64_t)));
|
auto value = TRY(convert_node(TRY(parse_node(context)), ConvInteger, sizeof(uint64_t)));
|
||||||
|
|
||||||
if (obj_ref == nullptr)
|
dwarnln("TODO: handle notify({}, {})", object.elem2->node, value);
|
||||||
return {};
|
|
||||||
|
|
||||||
dwarnln("TODO: handle notify({}, {})", obj_ref->node, value);
|
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
|
@ -692,7 +692,9 @@ namespace Kernel
|
||||||
if (options & ~(WCONTINUED | WNOHANG | WUNTRACED))
|
if (options & ~(WCONTINUED | WNOHANG | WUNTRACED))
|
||||||
return BAN::Error::from_errno(EINVAL);
|
return BAN::Error::from_errno(EINVAL);
|
||||||
|
|
||||||
// FIXME: Add WCONTINUED and WUNTRACED when stopped/continued processes are added
|
// FIXME: support options stopped processes
|
||||||
|
if (options & ~(WCONTINUED | WUNTRACED))
|
||||||
|
return BAN::Error::from_errno(ENOTSUP);
|
||||||
|
|
||||||
const auto pid_matches =
|
const auto pid_matches =
|
||||||
[&](const ChildExitStatus& child)
|
[&](const ChildExitStatus& child)
|
||||||
|
|
|
@ -270,9 +270,7 @@ namespace Kernel
|
||||||
{
|
{
|
||||||
if (!m_disk_cache.has_value())
|
if (!m_disk_cache.has_value())
|
||||||
return BAN::Error::from_errno(EIO);
|
return BAN::Error::from_errno(EIO);
|
||||||
for (size_t i = 0; i < sector_count; i++)
|
return m_disk_cache->write_to_cache(lba, buffer, true);
|
||||||
TRY(m_disk_cache->write_to_cache(lba + i, buffer.slice(i * sector_size(), sector_size()), true));
|
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_disk_cache.has_value())
|
if (!m_disk_cache.has_value())
|
||||||
|
|
|
@ -17,20 +17,22 @@ struct FILE
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
mode_t mode;
|
mode_t mode;
|
||||||
|
int buffer_type;
|
||||||
bool eof;
|
bool eof;
|
||||||
bool error;
|
bool error;
|
||||||
|
|
||||||
int pid;
|
int pid;
|
||||||
|
|
||||||
unsigned char inline_buffer[BUFSIZ];
|
int unget_char;
|
||||||
unsigned char* buffer;
|
|
||||||
uint32_t buffer_rd_size; // 0 write buffer
|
|
||||||
uint32_t buffer_size;
|
|
||||||
uint32_t buffer_idx;
|
|
||||||
int buffer_type;
|
|
||||||
|
|
||||||
unsigned char unget_buffer[12];
|
unsigned char inline_buffer_storage[BUFSIZ];
|
||||||
uint32_t unget_buf_idx;
|
unsigned char* write_buffer;
|
||||||
|
uint32_t wr_buf_size;
|
||||||
|
uint32_t wr_buf_index;
|
||||||
|
|
||||||
|
unsigned char read_buffer[BUFSIZ];
|
||||||
|
uint32_t rd_buf_size;
|
||||||
|
uint32_t rd_buf_index;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ScopeLock
|
struct ScopeLock
|
||||||
|
@ -46,7 +48,7 @@ struct ScopeLock
|
||||||
funlockfile(m_file);
|
funlockfile(m_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE* const m_file;
|
FILE* m_file;
|
||||||
};
|
};
|
||||||
|
|
||||||
static FILE s_files[FOPEN_MAX];
|
static FILE s_files[FOPEN_MAX];
|
||||||
|
@ -60,29 +62,16 @@ static void init_closed_file(FILE* file)
|
||||||
{
|
{
|
||||||
file->fd = -1;
|
file->fd = -1;
|
||||||
file->mode = 0;
|
file->mode = 0;
|
||||||
|
file->buffer_type = _IOLBF;
|
||||||
file->eof = false;
|
file->eof = false;
|
||||||
file->error = false;
|
file->error = false;
|
||||||
file->pid = -1;
|
file->pid = -1;
|
||||||
file->buffer = file->inline_buffer;
|
file->unget_char = EOF;
|
||||||
file->buffer_size = sizeof(file->inline_buffer);
|
file->write_buffer = file->inline_buffer_storage;
|
||||||
file->buffer_idx = 0;
|
file->wr_buf_size = BUFSIZ;
|
||||||
file->buffer_type = _IOFBF;
|
file->wr_buf_index = 0;
|
||||||
file->buffer_rd_size = 0;
|
file->rd_buf_size = 0;
|
||||||
file->unget_buf_idx = 0;
|
file->rd_buf_index = 0;
|
||||||
}
|
|
||||||
|
|
||||||
static int drop_read_buffer(FILE* file)
|
|
||||||
{
|
|
||||||
if (file->buffer_rd_size == 0)
|
|
||||||
return 0;
|
|
||||||
ASSERT(file->buffer_idx != 0);
|
|
||||||
if (file->buffer_idx == 1)
|
|
||||||
return 0;
|
|
||||||
if (syscall(SYS_SEEK, file->fd, file->buffer_idx - 1, SEEK_CUR) == -1)
|
|
||||||
return EOF;
|
|
||||||
file->buffer_rd_size = 0;
|
|
||||||
file->buffer_idx = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _init_stdio()
|
void _init_stdio()
|
||||||
|
@ -92,11 +81,9 @@ void _init_stdio()
|
||||||
|
|
||||||
s_files[STDIN_FILENO].fd = STDIN_FILENO;
|
s_files[STDIN_FILENO].fd = STDIN_FILENO;
|
||||||
s_files[STDIN_FILENO].mode = O_RDONLY;
|
s_files[STDIN_FILENO].mode = O_RDONLY;
|
||||||
s_files[STDIN_FILENO].buffer_type = _IOLBF;
|
|
||||||
|
|
||||||
s_files[STDOUT_FILENO].fd = STDOUT_FILENO;
|
s_files[STDOUT_FILENO].fd = STDOUT_FILENO;
|
||||||
s_files[STDOUT_FILENO].mode = O_WRONLY;
|
s_files[STDOUT_FILENO].mode = O_WRONLY;
|
||||||
s_files[STDOUT_FILENO].buffer_type = _IOLBF;
|
|
||||||
|
|
||||||
s_files[STDERR_FILENO].fd = STDERR_FILENO;
|
s_files[STDERR_FILENO].fd = STDERR_FILENO;
|
||||||
s_files[STDERR_FILENO].mode = O_WRONLY;
|
s_files[STDERR_FILENO].mode = O_WRONLY;
|
||||||
|
@ -104,7 +91,6 @@ void _init_stdio()
|
||||||
|
|
||||||
s_files[STDDBG_FILENO].fd = STDDBG_FILENO;
|
s_files[STDDBG_FILENO].fd = STDDBG_FILENO;
|
||||||
s_files[STDDBG_FILENO].mode = O_WRONLY;
|
s_files[STDDBG_FILENO].mode = O_WRONLY;
|
||||||
s_files[STDDBG_FILENO].buffer_type = _IOLBF;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void clearerr(FILE* file)
|
void clearerr(FILE* file)
|
||||||
|
@ -134,12 +120,10 @@ int dprintf(int fildes, const char* __restrict format, ...)
|
||||||
int fclose(FILE* file)
|
int fclose(FILE* file)
|
||||||
{
|
{
|
||||||
ScopeLock _(file);
|
ScopeLock _(file);
|
||||||
if (fflush(file) == EOF)
|
(void)fflush(file);
|
||||||
return EOF;
|
int ret = (close(file->fd) == -1) ? EOF : 0;
|
||||||
if (close(file->fd) == -1)
|
|
||||||
return EOF;
|
|
||||||
init_closed_file(file);
|
init_closed_file(file);
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static mode_t parse_mode_string(const char* mode_str)
|
static mode_t parse_mode_string(const char* mode_str)
|
||||||
|
@ -178,9 +162,9 @@ FILE* fdopen(int fd, const char* mode_str)
|
||||||
continue;
|
continue;
|
||||||
s_files[i].fd = fd;
|
s_files[i].fd = fd;
|
||||||
s_files[i].mode = mode & O_ACCMODE;
|
s_files[i].mode = mode & O_ACCMODE;
|
||||||
ASSERT(s_files[i].buffer == s_files[i].inline_buffer);
|
ASSERT(s_files[i].write_buffer == s_files[i].inline_buffer_storage);
|
||||||
ASSERT(s_files[i].buffer_size == BUFSIZ);
|
ASSERT(s_files[i].wr_buf_size == BUFSIZ);
|
||||||
ASSERT(s_files[i].buffer_idx == 0);
|
ASSERT(s_files[i].rd_buf_size == 0);
|
||||||
return &s_files[i];
|
return &s_files[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,41 +186,27 @@ int fflush(FILE* file)
|
||||||
{
|
{
|
||||||
if (file == nullptr)
|
if (file == nullptr)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
|
||||||
for (int i = 0; i < FOPEN_MAX; i++)
|
for (int i = 0; i < FOPEN_MAX; i++)
|
||||||
if (s_files[i].fd != -1)
|
if (s_files[i].fd != -1)
|
||||||
if (int err = fflush(&s_files[i]); err != 0)
|
if (int ret = fflush(&s_files[i]); ret != 0)
|
||||||
ret = err;
|
|
||||||
return ret;
|
return ret;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScopeLock _(file);
|
ScopeLock _(file);
|
||||||
|
|
||||||
if (file->fd == -1)
|
file->unget_char = EOF;
|
||||||
{
|
|
||||||
errno = EBADF;
|
|
||||||
return EOF;
|
|
||||||
}
|
|
||||||
|
|
||||||
file->unget_buf_idx = 0;
|
if (file->wr_buf_index == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (file->buffer_rd_size)
|
if (syscall(SYS_WRITE, file->fd, file->write_buffer, file->wr_buf_index) < 0)
|
||||||
return drop_read_buffer(file);
|
|
||||||
|
|
||||||
size_t written = 0;
|
|
||||||
while (written < file->buffer_idx)
|
|
||||||
{
|
|
||||||
ssize_t nwrite = write(file->fd, file->buffer + written, file->buffer_idx - written);
|
|
||||||
if (nwrite < 0)
|
|
||||||
{
|
{
|
||||||
file->error = true;
|
file->error = true;
|
||||||
return EOF;
|
return EOF;
|
||||||
}
|
}
|
||||||
written += nwrite;
|
|
||||||
}
|
|
||||||
|
|
||||||
file->buffer_idx = 0;
|
|
||||||
|
|
||||||
|
file->wr_buf_index = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,11 +254,8 @@ char* fgets(char* str, int size, FILE* file)
|
||||||
|
|
||||||
int fileno(FILE* fp)
|
int fileno(FILE* fp)
|
||||||
{
|
{
|
||||||
if (fp->fd == -1)
|
if (fp == nullptr)
|
||||||
{
|
return EBADF;
|
||||||
errno = EBADF;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return fp->fd;
|
return fp->fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,8 +285,9 @@ FILE* fopen(const char* pathname, const char* mode_str)
|
||||||
continue;
|
continue;
|
||||||
s_files[i].fd = fd;
|
s_files[i].fd = fd;
|
||||||
s_files[i].mode = mode & O_ACCMODE;
|
s_files[i].mode = mode & O_ACCMODE;
|
||||||
ASSERT(s_files[i].buffer == s_files[i].inline_buffer);
|
ASSERT(s_files[i].write_buffer == s_files[i].inline_buffer_storage);
|
||||||
ASSERT(s_files[i].buffer_size == BUFSIZ);
|
ASSERT(s_files[i].wr_buf_size == BUFSIZ);
|
||||||
|
ASSERT(s_files[i].rd_buf_size == 0);
|
||||||
return &s_files[i];
|
return &s_files[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -366,13 +334,12 @@ size_t fread(void* buffer, size_t size, size_t nitems, FILE* file)
|
||||||
if (target == 0)
|
if (target == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
unsigned char* ubuffer = static_cast<unsigned char*>(buffer);
|
|
||||||
while (nread < target)
|
while (nread < target)
|
||||||
{
|
{
|
||||||
int ch = getc_unlocked(file);
|
int ch = getc_unlocked(file);
|
||||||
if (ch == EOF)
|
if (ch == EOF)
|
||||||
break;
|
break;
|
||||||
ubuffer[nread++] = ch;
|
static_cast<unsigned char*>(buffer)[nread++] = ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
return nread / size;
|
return nread / size;
|
||||||
|
@ -428,12 +395,13 @@ int fseek(FILE* file, long offset, int whence)
|
||||||
int fseeko(FILE* file, off_t offset, int whence)
|
int fseeko(FILE* file, off_t offset, int whence)
|
||||||
{
|
{
|
||||||
ScopeLock _(file);
|
ScopeLock _(file);
|
||||||
if (fflush(file) == EOF)
|
file->unget_char = EOF;
|
||||||
return -1;
|
|
||||||
long ret = syscall(SYS_SEEK, file->fd, offset, whence);
|
long ret = syscall(SYS_SEEK, file->fd, offset, whence);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
file->eof = false;
|
file->eof = false;
|
||||||
|
file->rd_buf_size = 0;
|
||||||
|
file->rd_buf_index = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -450,12 +418,10 @@ long ftell(FILE* file)
|
||||||
off_t ftello(FILE* file)
|
off_t ftello(FILE* file)
|
||||||
{
|
{
|
||||||
ScopeLock _(file);
|
ScopeLock _(file);
|
||||||
if (fflush(file) == EOF)
|
|
||||||
return -1;
|
|
||||||
long ret = syscall(SYS_TELL, file->fd);
|
long ret = syscall(SYS_TELL, file->fd);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
return ret;
|
return ret - (file->unget_char != EOF) - (file->rd_buf_size - file->rd_buf_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ftrylockfile(FILE*)
|
int ftrylockfile(FILE*)
|
||||||
|
@ -492,65 +458,38 @@ int getchar(void)
|
||||||
|
|
||||||
int getc_unlocked(FILE* file)
|
int getc_unlocked(FILE* file)
|
||||||
{
|
{
|
||||||
if (file->fd == -1 || !(file->mode & O_RDONLY))
|
|
||||||
{
|
|
||||||
errno = EBADF;
|
|
||||||
return EOF;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file->eof)
|
if (file->eof)
|
||||||
return EOF;
|
return EOF;
|
||||||
|
|
||||||
// read characters from ungetc
|
if (file->unget_char != EOF)
|
||||||
if (file->unget_buf_idx)
|
|
||||||
{
|
{
|
||||||
file->unget_buf_idx--;
|
int ch = file->unget_char;
|
||||||
unsigned char ch = file->unget_buffer[file->unget_buf_idx];
|
file->unget_char = EOF;
|
||||||
if (fseeko(file, 1, SEEK_CUR) == -1)
|
return (unsigned char)ch;
|
||||||
return EOF;
|
|
||||||
return ch;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// read from unbuffered file
|
if (file->rd_buf_index < file->rd_buf_size)
|
||||||
if (file->buffer_type == _IONBF)
|
return file->read_buffer[file->rd_buf_index++];
|
||||||
|
file->rd_buf_size = 0;
|
||||||
|
file->rd_buf_index = 0;
|
||||||
|
|
||||||
|
ssize_t nread = read(file->fd, file->read_buffer, sizeof(file->read_buffer));
|
||||||
|
|
||||||
|
if (nread < 0)
|
||||||
{
|
{
|
||||||
unsigned char ch;
|
file->error = true;
|
||||||
if (ssize_t nread = read(file->fd, &ch, 1); nread <= 0)
|
|
||||||
{
|
|
||||||
((nread == 0) ? file->eof : file->error) = true;
|
|
||||||
return EOF;
|
return EOF;
|
||||||
}
|
}
|
||||||
return ch;
|
|
||||||
}
|
|
||||||
|
|
||||||
// flush writable data
|
if (nread == 0)
|
||||||
if (file->buffer_rd_size == 0 && file->buffer_idx)
|
|
||||||
if (fflush(file) == EOF)
|
|
||||||
return EOF;
|
|
||||||
|
|
||||||
// buffered read
|
|
||||||
if (file->buffer_idx < file->buffer_rd_size)
|
|
||||||
{
|
{
|
||||||
unsigned char ch = file->buffer[file->buffer_idx];
|
file->eof = true;
|
||||||
file->buffer_idx++;
|
|
||||||
return ch;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (drop_read_buffer(file) == EOF)
|
|
||||||
return EOF;
|
|
||||||
|
|
||||||
// read into buffer
|
|
||||||
ssize_t nread = read(file->fd, file->buffer, file->buffer_size);
|
|
||||||
if (nread <= 0)
|
|
||||||
{
|
|
||||||
((nread == 0) ? file->eof : file->error) = true;
|
|
||||||
return EOF;
|
return EOF;
|
||||||
}
|
}
|
||||||
if (fseeko(file, 1 - nread, SEEK_CUR) == -1)
|
|
||||||
return EOF;
|
file->rd_buf_size = nread;
|
||||||
file->buffer_rd_size = nread;
|
file->rd_buf_index = 1;
|
||||||
file->buffer_idx = 1;
|
return file->read_buffer[0];
|
||||||
return file->buffer[0];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int getchar_unlocked(void)
|
int getchar_unlocked(void)
|
||||||
|
@ -563,11 +502,11 @@ char* gets(char* buffer)
|
||||||
if (stdin->eof)
|
if (stdin->eof)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
unsigned char* ubuffer = (unsigned char*)buffer;
|
||||||
|
|
||||||
int first = fgetc(stdin);
|
int first = fgetc(stdin);
|
||||||
if (first == EOF)
|
if (first == EOF)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
unsigned char* ubuffer = reinterpret_cast<unsigned char*>(buffer);
|
|
||||||
*ubuffer++ = first;
|
*ubuffer++ = first;
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
|
@ -663,8 +602,9 @@ FILE* popen(const char* command, const char* mode_str)
|
||||||
s_files[i].fd = read ? fds[0] : fds[1];
|
s_files[i].fd = read ? fds[0] : fds[1];
|
||||||
s_files[i].mode = (unsigned)(read ? O_RDONLY : O_WRONLY);
|
s_files[i].mode = (unsigned)(read ? O_RDONLY : O_WRONLY);
|
||||||
s_files[i].pid = pid;
|
s_files[i].pid = pid;
|
||||||
ASSERT(s_files[i].buffer == s_files[i].inline_buffer);
|
ASSERT(s_files[i].write_buffer == s_files[i].inline_buffer_storage);
|
||||||
ASSERT(s_files[i].buffer_size == BUFSIZ);
|
ASSERT(s_files[i].wr_buf_size == BUFSIZ);
|
||||||
|
ASSERT(s_files[i].rd_buf_size == 0);
|
||||||
return &s_files[i];
|
return &s_files[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -693,29 +633,8 @@ int putchar(int c)
|
||||||
|
|
||||||
int putc_unlocked(int c, FILE* file)
|
int putc_unlocked(int c, FILE* file)
|
||||||
{
|
{
|
||||||
if (file->fd == -1 || !(file->mode & O_WRONLY))
|
file->write_buffer[file->wr_buf_index++] = c;
|
||||||
{
|
if (file->buffer_type == _IONBF || (file->buffer_type == _IOLBF && c == '\n') || file->wr_buf_index >= file->wr_buf_size)
|
||||||
errno = EBADF;
|
|
||||||
return EOF;
|
|
||||||
}
|
|
||||||
|
|
||||||
file->unget_buf_idx = 0;
|
|
||||||
if (file->buffer_rd_size && drop_read_buffer(file) == EOF)
|
|
||||||
return EOF;
|
|
||||||
|
|
||||||
if (file->buffer_type == _IONBF)
|
|
||||||
{
|
|
||||||
ssize_t nwrite = write(file->fd, &c, 1);
|
|
||||||
if (nwrite == -1)
|
|
||||||
file->error = true;
|
|
||||||
if (nwrite <= 0)
|
|
||||||
return EOF;
|
|
||||||
return (unsigned char)c;
|
|
||||||
}
|
|
||||||
|
|
||||||
file->buffer[file->buffer_idx] = c;
|
|
||||||
file->buffer_idx++;
|
|
||||||
if ((file->buffer_type == _IOLBF && c == '\n') || file->buffer_idx >= file->buffer_size)
|
|
||||||
if (fflush(file) == EOF)
|
if (fflush(file) == EOF)
|
||||||
return EOF;
|
return EOF;
|
||||||
return (unsigned char)c;
|
return (unsigned char)c;
|
||||||
|
@ -827,21 +746,15 @@ int setvbuf(FILE* file, char* buffer, int type, size_t size)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size == 0)
|
if (buffer == nullptr)
|
||||||
type = _IONBF;
|
|
||||||
|
|
||||||
unsigned char* ubuffer = reinterpret_cast<unsigned char*>(buffer);
|
|
||||||
if (ubuffer == nullptr)
|
|
||||||
{
|
{
|
||||||
ubuffer = file->inline_buffer;
|
buffer = reinterpret_cast<char*>(file->inline_buffer_storage);
|
||||||
size = BAN::Math::min<size_t>(size, sizeof(file->inline_buffer));
|
size = BAN::Math::min<size_t>(size, BUFSIZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(file->buffer_rd_size == 0);
|
|
||||||
ASSERT(file->buffer_idx == 0);
|
|
||||||
file->buffer_type = type;
|
file->buffer_type = type;
|
||||||
file->buffer_size = size;
|
file->wr_buf_size = size;
|
||||||
file->buffer = ubuffer;
|
file->write_buffer = reinterpret_cast<unsigned char*>(buffer);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -876,10 +789,8 @@ int sscanf(const char* s, const char* format, ...)
|
||||||
// TODO
|
// TODO
|
||||||
char* tempnam(const char*, const char*);
|
char* tempnam(const char*, const char*);
|
||||||
|
|
||||||
FILE* tmpfile(void)
|
// TODO
|
||||||
{
|
FILE* tmpfile(void);
|
||||||
ASSERT_NOT_REACHED();
|
|
||||||
}
|
|
||||||
|
|
||||||
char* tmpnam(char* storage)
|
char* tmpnam(char* storage)
|
||||||
{
|
{
|
||||||
|
@ -899,23 +810,11 @@ char* tmpnam(char* storage)
|
||||||
|
|
||||||
int ungetc_unlocked(int c, FILE* stream)
|
int ungetc_unlocked(int c, FILE* stream)
|
||||||
{
|
{
|
||||||
if (stream->fd == -1)
|
if (c == EOF)
|
||||||
{
|
|
||||||
errno = EBADF;
|
|
||||||
return EOF;
|
return EOF;
|
||||||
}
|
if (stream->unget_char != EOF)
|
||||||
|
|
||||||
if (c == EOF || stream->unget_buf_idx >= sizeof(stream->unget_buffer))
|
|
||||||
{
|
|
||||||
errno = EINVAL;
|
|
||||||
return EOF;
|
return EOF;
|
||||||
}
|
stream->unget_char = c;
|
||||||
|
|
||||||
if (fseeko(stream, -1, SEEK_CUR) == -1)
|
|
||||||
return EOF;
|
|
||||||
|
|
||||||
stream->unget_buffer[stream->unget_buf_idx] = c;
|
|
||||||
stream->unget_buf_idx++;
|
|
||||||
stream->eof = false;
|
stream->eof = false;
|
||||||
return (unsigned char)c;
|
return (unsigned char)c;
|
||||||
}
|
}
|
||||||
|
@ -1062,3 +961,8 @@ int vsscanf(const char* s, const char* format, va_list arguments)
|
||||||
}, &s
|
}, &s
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FILE* tmpfile(void)
|
||||||
|
{
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue