47 LOG_DEBUG(
"process_file_get_process: inode private is NULL\n");
94 prioStr[
count] =
'\0';
96 long long int prio =
atoll(prioStr);
156 cwdStr[
count] =
'\0';
304 int length =
snprintf(statStr,
sizeof(statStr),
305 "user_clocks %llu\nkernel_clocks %llu\nstart_clocks %llu\nuser_pages %llu\nthread_count %llu", userClocks,
306 kernelClocks,
startTime, userPages, threadCount);
322 if (argc != 2 && argc != 3)
337 if (
sscanf(argv[1],
"%lld", &fd) != 1)
351 if (
sscanf(argv[1],
"%lld", &minFd) != 1)
358 if (
sscanf(argv[2],
"%lld", &maxFd) != 1)
388 if (
sscanf(argv[1],
"%lld", &oldFd) != 1)
395 if (
sscanf(argv[2],
"%lld", &newFd) != 1)
493 .
read = process_env_read,
584 LOG_DEBUG(
"freeing process pid=%d\n", process->
id);
595 panic(
NULL,
"Attempt to free process pid=%llu with present threads\n", process->
id);
763 if (process->
id != 0)
772 LOG_DEBUG(
"created process pid=%d\n", process->
id);
798 LOG_DEBUG(
"sent kill note to %llu threads in process pid=%d\n", killCount, process->
id);
877 if (argv ==
NULL || argc == 0)
889 totalSize +=
strlen(argv[i]) + 1;
897 char* cmdline =
malloc(totalSize);
904 char* dest = cmdline;
912 memcpy(dest, argv[i], len);
934 if (thread->
id == tid)
950 panic(
NULL,
"Failed to create kernel process");
962 if (procMount ==
NULL)
964 panic(
NULL,
"Failed to mount /proc filesystem");
970 panic(
NULL,
"Failed to create /proc/self directory");
978 panic(
NULL,
"Failed to create /proc/[pid] directory for kernel process");
992 if (
uptime < nextReaperTime)
1036 panic(
NULL,
"Failed to create process reaper thread");
#define MAX_NAME
Maximum length of names.
#define MAX_PATH
Maximum length of filepaths.
#define assert(expression)
#define SYSCALL_DEFINE(num, returnType,...)
Macro to define a syscall.
#define CTL_STANDARD_OPS_DEFINE(name,...)
Helper macro to define a standard ctl file operations structure.
void cwd_set(cwd_t *cwd, const path_t *newPath)
Set the current working directory.
void cwd_init(cwd_t *cwd)
Initialize a CWD structure.
void cwd_clear(cwd_t *cwd)
Clear the current working directory.
path_t cwd_get(cwd_t *cwd)
Get the current working directory.
void cwd_deinit(cwd_t *cwd)
Deinitialize a CWD structure.
void dentry_make_positive(dentry_t *dentry, inode_t *inode)
Make a dentry positive by associating it with an inode.
dentry_t * dentry_new(superblock_t *superblock, dentry_t *parent, const char *name)
Create a new dentry.
bool dentry_is_positive(dentry_t *dentry)
Check if a dentry is positive.
fd_t file_table_dup2(file_table_t *table, fd_t oldFd, fd_t newFd)
Duplicate a file descriptor to a specific file descriptor.
uint64_t file_table_free(file_table_t *table, fd_t fd)
Free a file descriptor.
void file_table_close_all(file_table_t *table)
Close all files in the file table.
void file_table_init(file_table_t *table)
Initialize a file table.
void file_table_deinit(file_table_t *table)
Deinitialize a file table.
uint64_t file_table_free_range(file_table_t *table, fd_t min, fd_t max)
Free a range of file descriptors.
uint64_t file_generic_seek(file_t *file, int64_t offset, seek_origin_t origin)
Helper function for basic seeking.
inode_t * inode_new(superblock_t *superblock, inode_number_t number, inode_type_t type, const inode_ops_t *ops, const file_ops_t *fileOps)
Create a new inode.
void namespace_init(namespace_t *ns)
Initializes a namespace.
mount_t * namespace_bind(namespace_t *ns, dentry_t *source, path_t *target, mount_flags_t flags, mode_t mode)
Bind a source dentry to a target path in a namespace.
void namespace_deinit(namespace_t *ns)
Clear and deinitialize a namespace.
void namespace_clear(namespace_t *ns)
Clears all mounts from a namespace.
mode_t
Path flags and permissions.
void path_put(path_t *path)
Put a path.
#define PATH_CREATE(inMount, inDentry)
Helper to create a path.
#define PATH_DEFER(path)
Defer path put.
uint64_t path_walk(path_t *path, const pathname_t *pathname, namespace_t *ns)
Walk a pathname to a path.
uint64_t pathname_init(pathname_t *pathname, const char *string)
Initialize a pathname.
uint64_t path_to_name(const path_t *path, pathname_t *pathname)
Convert a path to a pathname.
NORETURN void panic(const interrupt_frame_t *frame, const char *format,...)
Panic the kernel, printing a message and halting.
#define LOG_INFO(format,...)
#define LOG_DEBUG(format,...)
uint64_t space_user_page_count(space_t *space)
Get the number of user pages allocated in the address space.
void space_deinit(space_t *space)
Deinitializes a virtual address space.
uint64_t space_init(space_t *space, uintptr_t startAddress, uintptr_t endAddress, space_flags_t flags)
Initializes a virtual address space.
@ SPACE_MAP_KERNEL_HEAP
Map the kernel heap into the address space.
@ SPACE_MAP_IDENTITY
Map the identity mapped physical memory into the address space.
@ SPACE_MAP_KERNEL_BINARY
Map the kernel binary into the address space.
#define VMM_USER_SPACE_MAX
The maximum address for user space.
#define VMM_USER_SPACE_MIN
The minimum address for user space.
process_t * process_new(priority_t priority)
Allocates and initializes a new process.
void process_reaper_init(void)
Initializes the process reaper.
process_t * process_get_kernel(void)
Gets the kernel process.
bool process_has_thread(process_t *process, tid_t tid)
Checks if a process has a thread with the specified thread ID.
void process_procfs_init(void)
Initializes the /proc directory.
uint64_t process_set_cmdline(process_t *process, char **argv, uint64_t argc)
Sets the command line arguments for a process.
uint64_t process_copy_env(process_t *dest, process_t *src)
Copies the environment variables from one process to another.
void process_kill(process_t *process, int32_t status)
Kills a process.
uint64_t thread_send_note(thread_t *thread, const void *buffer, uint64_t count)
Send a note to a thread.
tid_t thread_kernel_create(thread_kernel_entry_t entry, void *arg)
Creates a new thread that runs in kernel mode and submits it to the scheduler.
uint64_t wait_unblock(wait_queue_t *queue, uint64_t amount, errno_t err)
Unblock threads waiting on a wait queue.
void wait_queue_deinit(wait_queue_t *queue)
Deinitialize wait queue.
#define WAIT_ALL
Used to indicate that the wait should unblock all waiting threads.
void wait_queue_init(wait_queue_t *queue)
Initialize wait queue.
#define WAIT_BLOCK(queue, condition)
Blocks until the condition is true, will test the condition on every wakeup.
process_t * sched_process(void)
Retrieves the process of the currently running thread.
uint64_t sched_nanosleep(clock_t timeout)
Sleeps the current thread for a specified duration in nanoseconds.
void futex_ctx_deinit(futex_ctx_t *ctx)
Deinitialize a per-process futex context. *.
void futex_ctx_init(futex_ctx_t *ctx)
Initialize a per-process futex context.
static void lock_init(lock_t *lock)
Initializes a lock.
#define LOCK_CREATE()
Create a lock initializer.
#define LOCK_SCOPE(lock)
Acquires a lock for the reminder of the current scope.
static void lock_release(lock_t *lock)
Releases a lock.
static void lock_acquire(lock_t *lock)
Acquires a lock, blocking until it is available.
#define MUTEX_SCOPE(mutex)
Acquires a mutex for the reminder of the current scope.
clock_t sys_time_uptime(void)
Time since boot.
#define UNREF_DEFER(ptr)
RAII-style cleanup for scoped references.
static void ref_init(ref_t *ref, void *free)
Initialize a reference counter.
#define REF(ptr)
Increment reference count.
#define UNREF(ptr)
Decrement reference count.
#define BUFFER_READ(buffer, count, offset, src, size)
Helper macros for implementing file operations dealing with simple buffers.
#define BUFFER_WRITE(buffer, count, offset, src, size)
Helper macro for implementing file operations dealing with simple buffer writes.
uint64_t vfs_id_get(void)
Generates a new unique ID, to be used for any VFS object.
#define CONFIG_PROCESS_REAPER_INTERVAL
Process reaper interval configuration.
#define ENOENT
No such file or directory.
#define EINVAL
Invalid argument.
#define ENOMEM
Out of memory.
#define EBUSY
Device or resource busy.
#define errno
Error number variable.
#define EACCES
Permission denied.
poll_events_t
Poll events type.
@ MOUNT_PROPAGATE_PARENT
Propagate the mount to parent namespaces.
@ MOUNT_OVERWRITE
Overwrite any existing mount at the mountpoint.
@ MOUNT_PROPAGATE_CHILDREN
Propagate the mount to child namespaces.
@ POLLIN
File descriptor is ready to read.
#define LIST_FOR_EACH(elem, list, member)
Iterates over a list.
static list_entry_t * list_first(list_t *list)
Gets the first entry in the list without removing it.
static list_entry_t * list_pop_first(list_t *list)
Pops the first entry from the list.
static uint64_t list_length(list_t *list)
Gets the length of the list.
static void list_push_back(list_t *list, list_entry_t *entry)
Pushes an entry to the end of the list.
#define LIST_CREATE(name)
Creates a list initializer.
static void list_remove(list_t *list, list_entry_t *entry)
Removes a list entry from its current list.
static bool list_is_empty(list_t *list)
Checks if a list is empty.
static void list_entry_init(list_entry_t *entry)
Initializes a list entry.
static void list_init(list_t *list)
Initializes a list.
#define PRIORITY_MAX_USER
The maximum priority user space is allowed to specify, inclusive.
clock_t uptime(void)
System call for retreving the time since boot.
#define PRIORITY_MAX
The maximum priority value, inclusive.
uint8_t priority_t
Priority type.
#define NULL
Pointer error value.
#define ERR
Integer error value.
#define CONTAINER_OF(ptr, type, member)
Container of macro.
__UINT64_TYPE__ tid_t
Thread Identifier.
__UINT64_TYPE__ fd_t
A file descriptor.
__UINT64_TYPE__ pid_t
Process Identifier.
#define CONTAINER_OF_SAFE(ptr, type, member)
Safe container of macro.
__UINT64_TYPE__ clock_t
A nanosecond time.
EFI_PHYSICAL_ADDRESS buffer
static uint64_t process_dir_init(process_t *process)
static uint64_t process_ctl_dup2(file_t *file, uint64_t argc, const char **argv)
static inode_ops_t inodeOps
static uint64_t process_cmdline_read(file_t *file, void *buffer, uint64_t count, uint64_t *offset)
static uint64_t process_env_create(inode_t *dir, dentry_t *target, mode_t mode)
static void process_env_cleanup(inode_t *inode)
static void process_cleanup(inode_t *inode)
static wait_queue_t * process_wait_poll(file_t *file, poll_events_t *revents)
static uint64_t process_env_remove(inode_t *parent, dentry_t *target, mode_t mode)
static file_ops_t noteOps
static uint64_t process_ctl_close(file_t *file, uint64_t argc, const char **argv)
static file_ops_t envFileOps
static uint64_t process_wait_read(file_t *file, void *buffer, uint64_t count, uint64_t *offset)
static file_ops_t prioOps
static process_t * kernelProcess
static uint64_t process_note_write(file_t *file, const void *buffer, uint64_t count, uint64_t *offset)
static uint64_t process_stat_read(file_t *file, void *buffer, uint64_t count, uint64_t *offset)
static uint64_t process_ctl_kill(file_t *file, uint64_t argc, const char **argv)
static void process_reaper(void *arg)
static uint64_t process_prio_write(file_t *file, const void *buffer, uint64_t count, uint64_t *offset)
static uint64_t process_ctl_start(file_t *file, uint64_t argc, const char **argv)
static void process_free(process_t *process)
static inode_ops_t envInodeOps
static uint64_t process_prio_read(file_t *file, void *buffer, uint64_t count, uint64_t *offset)
static file_ops_t waitOps
static file_ops_t statOps
static uint64_t process_env_write(file_t *file, const void *buffer, uint64_t count, uint64_t *offset)
static uint64_t process_cwd_read(file_t *file, void *buffer, uint64_t count, uint64_t *offset)
static uint64_t process_cwd_write(file_t *file, const void *buffer, uint64_t count, uint64_t *offset)
static file_ops_t cmdlineOps
#define atomic_store(object, desired)
#define atomic_fetch_or(object, operand)
#define atomic_load(object)
#define ATOMIC_VAR_INIT(value)
#define atomic_fetch_and(object, operand)
#define atomic_fetch_add(object, operand)
#define atomic_init(obj, value)
_PUBLIC int sscanf(const char *_RESTRICT s, const char *_RESTRICT format,...)
_PUBLIC int snprintf(char *_RESTRICT s, size_t n, const char *_RESTRICT format,...)
_PUBLIC void * realloc(void *ptr, size_t size)
_PUBLIC long long int atoll(const char *nptr)
_PUBLIC void * malloc(size_t size)
_PUBLIC void free(void *ptr)
_PUBLIC void * memcpy(void *_RESTRICT s1, const void *_RESTRICT s2, size_t n)
_PUBLIC size_t strlen(const char *s)
_PUBLIC void * memset(void *s, int c, size_t n)
Directory entry structure.
inode_t * inode
Will be NULL if the dentry is negative, once positive it will never be NULL.
char name[MAX_NAME]
Constant after creation.
list_entry_t otherEntry
Made available for use by any other subsystems for convenience.
File operations structure.
uint64_t(* write)(file_t *file, const void *buffer, uint64_t count, uint64_t *offset)
uint64_t(* read)(file_t *file, void *buffer, uint64_t count, uint64_t *offset)
Inode operations structure.
void(* cleanup)(inode_t *inode)
Cleanup function called when the inode is being freed.
uint64_t(* create)(inode_t *dir, dentry_t *target, mode_t mode)
Handles both directories and files depending on mode.
superblock_t * superblock
Constant after creation.
A simple ticket lock implementation.
dentry_t * source
The dentry to appear at target once mounted, usually the root dentry of the mounted filesystem.
clock_t startTime
The time when the process was started.
mount_t * self
The /proc/self bind mount.
list_t envVars
List of dentries in the /proc/[pid]/env/ directory.
wait_queue_t suspendQueue
dentry_t * proc
The /proc/[pid] directory, also stored in dentries for convenience.
list_t dentries
List of dentries in the /proc/[pid]/ directory.
dentry_t * env
The /proc/[pid]/env directory, also stored in dentries for convenience.
process_threads_t threads
Thread of execution structure.
tid_t id
The thread id, unique within a process_t.
The primitive that threads block on.
mount_t * sysfs_mount_new(const path_t *parent, const char *name, namespace_t *ns, mount_flags_t flags, mode_t mode, const superblock_ops_t *superblockOps)
Mount a new instance of SysFS.
dentry_t * sysfs_dir_new(dentry_t *parent, const char *name, const inode_ops_t *inodeOps, void *private)
Create a new directory inside a mounted SysFS instance.
dentry_t * sysfs_file_new(dentry_t *parent, const char *name, const inode_ops_t *inodeOps, const file_ops_t *fileOps, void *private)
Create a new file inside a mounted SysFS instance.