Compare commits

..

6 Commits

Author SHA1 Message Date
7b88b9cea3
kernel/ext2: Replace a manually allocated buffer with Buffer
Some checks failed
continuous-integration/drone/push Build is failing
2023-08-16 09:15:29 +02:00
54cc80f649
kernel/ATA: Replace a manually allocated buffer with Buffer
This also lets us keep it empty unless it is used, in which case we resize it (if it wasn't already resized).
2023-08-16 09:15:00 +02:00
b8f81502b8
kernel: Fix some debug messages that are not shown by default 2023-08-16 09:03:25 +02:00
e8e05159c1
libluna+kernel: Make CRC32 a class 2023-08-15 19:27:09 +02:00
49a6c39c38
libc: Implement popen() and pclose() 2023-08-15 19:21:25 +02:00
706752d6b9
kernel: Return SIGPIPE/EPIPE when writing to a pipe with no more readers 2023-08-15 19:08:37 +02:00
11 changed files with 131 additions and 30 deletions

View File

@ -6,6 +6,7 @@
#include "fs/MBR.h"
#include "memory/MemoryManager.h"
#include <luna/Alignment.h>
#include <luna/Buffer.h>
#include <luna/CType.h>
#include <luna/SafeArithmetic.h>
#include <luna/Vector.h>
@ -758,9 +759,7 @@ Result<u64> ATADevice::read(u8* buf, usize offset, usize size) const
ScopedKMutexLock<100> lock(m_drive->channel()->lock());
// FIXME: Don't always allocate this if we don't need it.
auto* temp = (u8*)TRY(malloc_impl(block_size));
auto guard = make_scope_guard([temp] { free_impl(temp); });
Buffer temp;
if (offset % block_size)
{
@ -769,8 +768,10 @@ Result<u64> ATADevice::read(u8* buf, usize offset, usize size) const
// Maybe we don't even want enough to get to the next block?
if (extra_size > size) extra_size = size;
TRY(m_drive->read_lba(offset / block_size, temp, 1));
memcpy(buf, temp + (offset % block_size), extra_size);
TRY(temp.try_resize(block_size));
TRY(m_drive->read_lba(offset / block_size, temp.data(), 1));
memcpy(buf, temp.data() + (offset % block_size), extra_size);
offset += extra_size;
size -= extra_size;
buf += extra_size;
@ -794,8 +795,9 @@ Result<u64> ATADevice::read(u8* buf, usize offset, usize size) const
if (size)
{
TRY(m_drive->read_lba(offset / block_size, temp, 1));
memcpy(buf, temp, size);
TRY(temp.try_resize(block_size));
TRY(m_drive->read_lba(offset / block_size, temp.data(), 1));
memcpy(buf, temp.data(), size);
}
return length;

View File

@ -66,6 +66,9 @@ namespace GPT
{
header.checksum = 0;
return CRC32::checksum((u8*)&header, 0x5c);
CRC32 crc;
crc.append((u8*)&header, 0x5c);
return crc.digest();
}
}

View File

@ -44,7 +44,11 @@ Result<usize> Pipe::read(u8* buf, usize, usize length)
Result<usize> Pipe::write(const u8* buf, usize, usize length)
{
if (!m_reader) return length;
if (!m_reader)
{
Scheduler::current()->send_signal(SIGPIPE);
return err(EPIPE);
}
u8* slice = TRY(m_data_buffer.slice_at_end(length));
memcpy(slice, buf, length);

View File

@ -63,7 +63,7 @@ namespace Ext2
#ifdef EXT2_DEBUG
kdbgln("ext2: Read inode %lu with mode %#x (%#x + %#o), size %lu", inum, inode->m_raw_inode.mode,
inode->m_raw_inode.mode & 0xf000, inode->mode(), inode->size());
inode->m_raw_inode.mode & 0xf000, inode->metadata().mode, inode->metadata().size);
#endif
m_inode_cache.try_set(inum, inode);

View File

@ -91,19 +91,18 @@ namespace Ext2
const usize inode_size = m_metadata.size;
const usize block_size = m_fs->m_block_size;
u8* const buf = (u8*)TRY(calloc_impl(block_size, 1));
auto guard = make_scope_guard([buf] { free_impl(buf); });
auto buf = TRY(Buffer::create_sized(block_size));
m_entries.clear();
for (usize offset = 0; offset < inode_size; offset += block_size)
{
TRY(read(buf, offset, block_size));
TRY(read(buf.data(), offset, block_size));
usize dir_offset = 0;
while (dir_offset < block_size)
{
auto& entry = *(Ext2::RawDirectoryEntry*)&buf[dir_offset];
auto& entry = *(Ext2::RawDirectoryEntry*)&buf.data()[dir_offset];
if (entry.inum != 0)
{

View File

@ -182,7 +182,7 @@ Result<u64> sys_fork(Registers* regs, SyscallArgs)
Scheduler::add_thread(thread);
#ifdef FORK_DEBUG
kdbgln("fork: thread %lu forked into child %lu", current->id, thread->id);
kdbgln("fork: thread %d forked into child %d", current->id, thread->id);
#endif
return thread->id;

View File

@ -183,7 +183,7 @@ namespace Scheduler
CPU::disable_interrupts();
#ifdef REAP_DEBUG
kdbgln("reap: reaping thread with id %zu", thread->id);
kdbgln("reap: reaping thread with id %d", thread->id);
#endif
if (thread->is_kernel)

View File

@ -27,6 +27,7 @@ typedef struct
int mode; // The buffering mode.
} _buf;
int _flags; // The file access mode with which the file was opened.
pid_t _pid; // For popen(3) files, the pid of the child process.
} FILE;
#define EOF -1
@ -52,6 +53,7 @@ extern "C"
{
#endif
/* Flush a stream's buffers. */
int fflush(FILE*);
/* Open a file and bind a stream to it. */
@ -201,6 +203,9 @@ extern "C"
/* Move a file's location across a file system. */
int rename(const char* oldpath, const char* newpath);
/* Pipe a stream to or from a process. */
FILE* popen(const char* command, const char* type);
#ifdef __cplusplus
}
#endif

View File

@ -6,6 +6,7 @@
#include <stdlib.h>
#include <string.h>
#include <sys/syscall.h>
#include <sys/wait.h>
#include <unistd.h>
FILE* stdin = nullptr;
@ -761,4 +762,87 @@ extern "C"
unlink(oldpath);
return 0;
}
FILE* popen(const char* command, const char* type)
{
int pfds[2];
if (pipe(pfds) < 0) return nullptr;
if (*type != 'r' && *type != 'w')
{
errno = EINVAL;
return nullptr;
}
pid_t child = fork();
if (child < 0)
{
close(pfds[0]);
close(pfds[1]);
return nullptr;
}
if (child == 0)
{
if (*type == 'r')
{
close(pfds[0]);
dup2(pfds[1], STDOUT_FILENO);
}
else
{
close(pfds[1]);
dup2(pfds[0], STDIN_FILENO);
}
execl("/bin/sh", "sh", "-c", command, nullptr);
_exit(127);
}
int fd;
if (*type == 'r')
{
close(pfds[1]);
fd = pfds[0];
}
else
{
close(pfds[0]);
fd = pfds[1];
}
int err = errno;
FILE* f = (FILE*)malloc(sizeof(FILE));
if (!f)
{
errno = err;
close(fd);
return nullptr;
}
f->_fd = fd;
f->_pid = child;
clearerr(f);
f->_flags = *type == 'r' ? O_RDONLY : O_WRONLY;
f->_buf.status = 0;
f->_buf.mode = _IOFBF;
f->_buf.size = f->_buf.index = 0;
f->_buf.buffer = nullptr;
setvbuf(f, NULL, f->_buf.mode, 0);
s_open_files[fd] = f;
return f;
}
int pclose(FILE* stream)
{
pid_t pid = stream->_pid;
fclose(stream);
int status;
if (waitpid(pid, &status, 0) < 0) return -1;
return status;
}
}

View File

@ -1,7 +1,13 @@
#pragma once
#include <luna/Types.h>
namespace CRC32
class CRC32
{
u32 checksum(const u8* data, usize size);
}
public:
void append(const u8* data, usize size);
u32 digest();
private:
u32 m_checksum = 0xffffffffu;
};

View File

@ -33,18 +33,16 @@ static const u32 crc_table[] = {
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
namespace CRC32
void CRC32::append(const u8* data, usize size)
{
u32 checksum(const u8* data, usize size)
{
u32 crc = 0xffffffffu;
for (usize i = 0; i < size; i++)
{
const u32 index = (crc & 0xff) ^ data[i];
crc = (crc >> 8) ^ (crc_table[index]);
const u32 index = (m_checksum & 0xff) ^ data[i];
m_checksum = (m_checksum >> 8) ^ (crc_table[index]);
}
}
return ~crc;
}
u32 CRC32::digest()
{
return ~m_checksum;
}