54 lines
1.6 KiB
C
54 lines
1.6 KiB
C
// SPDX-License-Identifier: ISC
|
|
|
|
#include <zinnia/exec.h>
|
|
#include <zinnia/mutex.h>
|
|
#include <zinnia/print.h>
|
|
#include <zinnia/process.h>
|
|
#include <zinnia/tailq.h>
|
|
#include <zinnia/vfs.h>
|
|
|
|
static mutex_t formats_lock;
|
|
static tailq_head(struct exec_format) formats = {nullptr, &formats.tqh_first};
|
|
|
|
struct exec_format* exec_identify(struct vmo* obj) {
|
|
mutex_lock(&formats_lock);
|
|
struct exec_format* format = tailq_first(&formats);
|
|
while (format != nullptr && !format->identify(obj))
|
|
format = tailq_next(format, link);
|
|
mutex_unlock(&formats_lock);
|
|
return format;
|
|
}
|
|
|
|
void exec_register(struct exec_format* format) {
|
|
mutex_lock(&formats_lock);
|
|
tailq_insert_tail(&formats, format, link);
|
|
mutex_unlock(&formats_lock);
|
|
|
|
log("exec: Registered new exec format \"%s\"\n", format->name);
|
|
}
|
|
|
|
errno_t exec_open(struct process* proc, const char* path, struct vmo** out) {
|
|
mutex_lock(&proc->lock);
|
|
struct vfs_path root = vfs_path_clone(proc->root);
|
|
struct vfs_path cwd = vfs_path_clone(proc->cwd);
|
|
mutex_unlock(&proc->lock);
|
|
|
|
struct vfs_file* file;
|
|
errno_t status = vfs_file_open(root, cwd, path, O_RDONLY | O_EXEC, 0, &proc->identity, &file);
|
|
vfs_path_drop(root);
|
|
vfs_path_drop(cwd);
|
|
if (status)
|
|
return status;
|
|
|
|
status = exec_file_object(proc, file, out);
|
|
vfs_file_unref(file);
|
|
return status;
|
|
}
|
|
|
|
errno_t exec_file_object(struct process* proc, struct vfs_file* file, struct vmo** out) {
|
|
errno_t status = vfs_node_check_exec(file->vnode, &proc->identity);
|
|
if (!status)
|
|
status = vfs_file_get_object(file, out);
|
|
return status;
|
|
}
|