Kernel, libc: Implement O_CLOEXEC
This commit is contained in:
parent
fb88459263
commit
0faabe02e5
@ -32,7 +32,7 @@ struct Descriptor
|
|||||||
ssize_t read(size_t size, char* buffer);
|
ssize_t read(size_t size, char* buffer);
|
||||||
ssize_t write(size_t size, const char* buffer);
|
ssize_t write(size_t size, const char* buffer);
|
||||||
|
|
||||||
void open(VFS::Node* node, bool can_read, bool can_write, bool able_to_block);
|
void open(VFS::Node* node, bool can_read, bool can_write, bool able_to_block, bool close_on_exec);
|
||||||
|
|
||||||
int seek(long offset);
|
int seek(long offset);
|
||||||
long offset()
|
long offset()
|
||||||
@ -50,6 +50,11 @@ struct Descriptor
|
|||||||
return m_able_to_block;
|
return m_able_to_block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool close_on_exec()
|
||||||
|
{
|
||||||
|
return m_close_on_exec;
|
||||||
|
}
|
||||||
|
|
||||||
Descriptor(const Descriptor& other);
|
Descriptor(const Descriptor& other);
|
||||||
Descriptor();
|
Descriptor();
|
||||||
|
|
||||||
@ -60,6 +65,7 @@ struct Descriptor
|
|||||||
bool m_can_read;
|
bool m_can_read;
|
||||||
bool m_can_write;
|
bool m_can_write;
|
||||||
bool m_able_to_block;
|
bool m_able_to_block;
|
||||||
|
bool m_close_on_exec;
|
||||||
VFS::Node* m_node;
|
VFS::Node* m_node;
|
||||||
uint64_t m_offset;
|
uint64_t m_offset;
|
||||||
};
|
};
|
@ -7,15 +7,17 @@ Descriptor::Descriptor() : m_is_open(false)
|
|||||||
|
|
||||||
Descriptor::Descriptor(const Descriptor& other)
|
Descriptor::Descriptor(const Descriptor& other)
|
||||||
: m_is_open(other.m_is_open), m_can_read(other.m_can_read), m_can_write(other.m_can_write),
|
: m_is_open(other.m_is_open), m_can_read(other.m_can_read), m_can_write(other.m_can_write),
|
||||||
m_able_to_block(other.m_able_to_block), m_node(other.m_node), m_offset(other.m_offset)
|
m_able_to_block(other.m_able_to_block), m_close_on_exec(other.m_close_on_exec), m_node(other.m_node),
|
||||||
|
m_offset(other.m_offset)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Descriptor::open(VFS::Node* node, bool can_read, bool can_write, bool able_to_block)
|
void Descriptor::open(VFS::Node* node, bool can_read, bool can_write, bool able_to_block, bool close_on_exec)
|
||||||
{
|
{
|
||||||
m_can_read = can_read;
|
m_can_read = can_read;
|
||||||
m_can_write = can_write;
|
m_can_write = can_write;
|
||||||
m_able_to_block = able_to_block;
|
m_able_to_block = able_to_block;
|
||||||
|
m_close_on_exec = close_on_exec;
|
||||||
m_node = node;
|
m_node = node;
|
||||||
m_offset = 0;
|
m_offset = 0;
|
||||||
m_is_open = true;
|
m_is_open = true;
|
||||||
@ -51,5 +53,6 @@ const Descriptor& Descriptor::operator=(const Descriptor& other)
|
|||||||
m_offset = other.m_offset;
|
m_offset = other.m_offset;
|
||||||
m_node = other.m_node;
|
m_node = other.m_node;
|
||||||
m_able_to_block = other.m_able_to_block;
|
m_able_to_block = other.m_able_to_block;
|
||||||
|
m_close_on_exec = other.m_close_on_exec;
|
||||||
return other;
|
return other;
|
||||||
}
|
}
|
@ -123,6 +123,12 @@ void sys_exec(Context* context, const char* pathname)
|
|||||||
|
|
||||||
Scheduler::reset_task(task, image);
|
Scheduler::reset_task(task, image);
|
||||||
|
|
||||||
|
for (int i = 0; i < TASK_MAX_FDS; i++)
|
||||||
|
{
|
||||||
|
Descriptor& file = task->files[i];
|
||||||
|
if (file.close_on_exec()) { file.close(); }
|
||||||
|
}
|
||||||
|
|
||||||
task->restore_context(context);
|
task->restore_context(context);
|
||||||
|
|
||||||
kfree(kpathname);
|
kfree(kpathname);
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#define OPEN_READ 1
|
#define OPEN_READ 1
|
||||||
#define OPEN_WRITE 2
|
#define OPEN_WRITE 2
|
||||||
#define OPEN_NONBLOCK 4
|
#define OPEN_NONBLOCK 4
|
||||||
|
#define OPEN_CLOEXEC 8
|
||||||
|
|
||||||
#define SEEK_SET 0
|
#define SEEK_SET 0
|
||||||
#define SEEK_CUR 1
|
#define SEEK_CUR 1
|
||||||
@ -181,6 +182,7 @@ void sys_open(Context* context, const char* filename, int flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool able_to_block = (flags & OPEN_NONBLOCK) == 0;
|
bool able_to_block = (flags & OPEN_NONBLOCK) == 0;
|
||||||
|
bool close_on_exec = (flags & OPEN_CLOEXEC) > 0;
|
||||||
|
|
||||||
kdbgln("open(): opening %s %s, allocated file descriptor %d", kfilename,
|
kdbgln("open(): opening %s %s, allocated file descriptor %d", kfilename,
|
||||||
(can_read && can_write) ? "rw"
|
(can_read && can_write) ? "rw"
|
||||||
@ -189,7 +191,7 @@ void sys_open(Context* context, const char* filename, int flags)
|
|||||||
fd);
|
fd);
|
||||||
|
|
||||||
kfree(kfilename);
|
kfree(kfilename);
|
||||||
current_task->files[fd].open(node, can_read, can_write, able_to_block);
|
current_task->files[fd].open(node, can_read, can_write, able_to_block, close_on_exec);
|
||||||
context->rax = fd;
|
context->rax = fd;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -225,7 +227,9 @@ void sys_read(Context* context, int fd, size_t size, char* buffer)
|
|||||||
current_task->blocking_read_info.size = size;
|
current_task->blocking_read_info.size = size;
|
||||||
return Scheduler::task_yield(context);
|
return Scheduler::task_yield(context);
|
||||||
}
|
}
|
||||||
ssize_t result = current_task->files[fd].read(size, (char*)VMM::get_physical((uint64_t)buffer));
|
ssize_t result = current_task->files[fd].read(
|
||||||
|
size, (char*)VMM::get_physical((uint64_t)buffer)); // FIXME: Handle errors, and big buffers which may not be
|
||||||
|
// across continuous physical pages.
|
||||||
context->rax = (size_t)result;
|
context->rax = (size_t)result;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
#define O_RDWR 3
|
#define O_RDWR 3
|
||||||
/* Open without blocking. */
|
/* Open without blocking. */
|
||||||
#define O_NONBLOCK 4
|
#define O_NONBLOCK 4
|
||||||
|
/* Close the opened file descriptor on a call to execve(). */
|
||||||
|
#define O_CLOEXEC 8
|
||||||
|
|
||||||
/* Duplicate a file descriptor. */
|
/* Duplicate a file descriptor. */
|
||||||
#define F_DUPFD 0
|
#define F_DUPFD 0
|
||||||
|
Loading…
Reference in New Issue
Block a user