1/*
2 * Copyright (C) 2020-2022 The opuntiaOS Project Authors.
3 * + Contributed by Nikita Melekhin <nimelehin@gmail.com>
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9#ifndef _KERNEL_TASKING_PROC_H
10#define _KERNEL_TASKING_PROC_H
11
12#include <algo/dynamic_array.h>
13#include <fs/vfs.h>
14#include <io/tty/tty.h>
15#include <libkern/atomic.h>
16#include <libkern/lock.h>
17#include <libkern/types.h>
18#include <mem/kmemzone.h>
19#include <mem/memzone.h>
20#include <mem/vmm.h>
21
22#define MAX_PROCESS_COUNT 1024
23#define MAX_OPENED_FILES 16
24
25struct blocker;
26
27enum PROC_STATUS {
28 PROC_INVALID = 0,
29 PROC_ALIVE,
30 PROC_DEAD,
31 PROC_DYING,
32 PROC_ZOMBIE,
33};
34
35struct thread;
36struct proc {
37 pdirectory_t* pdir;
38 pid_t pid;
39 pid_t ppid;
40 pid_t pgid;
41 uint32_t prio;
42 uint32_t status;
43 struct thread* main_thread;
44
45 // Locking order is important, vm_lock could not be acquired while lock is busy.
46 lock_t vm_lock;
47 lock_t lock;
48
49 uid_t uid;
50 gid_t gid;
51 uid_t euid;
52 gid_t egid;
53 uid_t suid;
54 gid_t sgid;
55
56 dynamic_array_t zones;
57
58 dentry_t* proc_file;
59 dentry_t* cwd;
60 file_descriptor_t* fds;
61 tty_entry_t* tty;
62
63 int exit_code;
64
65 bool is_kthread;
66
67 /* Trace data */
68 bool is_tracee;
69};
70typedef struct proc proc_t;
71
72/**
73 * PROC FUNCTIONS
74 */
75uint32_t proc_alloc_pid();
76struct thread* thread_by_pid(pid_t pid);
77
78int proc_init_storage();
79int proc_setup(proc_t* p);
80int proc_setup_with_uid(proc_t* p, uid_t uid, gid_t gid);
81int proc_setup_tty(proc_t* p, tty_entry_t* tty);
82int proc_fill_up_stack(proc_t* p, int argc, char** argv, char** env);
83int proc_free(proc_t* p);
84int proc_free_lockless(proc_t* p);
85
86struct thread* proc_alloc_thread();
87struct thread* proc_create_thread(proc_t* p);
88void proc_kill_all_threads(proc_t* p);
89void proc_kill_all_threads_except(proc_t* p, struct thread* gthread);
90
91/**
92 * KTHREAD FUNCTIONS
93 */
94
95int kthread_setup(proc_t* p);
96int kthread_setup_regs(proc_t* p, void* entry_point);
97void kthread_setup_segment_regs(proc_t* p);
98int kthread_fill_up_stack(struct thread* thread, void* data);
99int kthread_free(proc_t* p);
100
101int proc_load(proc_t* p, struct thread* main_thread, const char* path);
102int proc_fork_from(proc_t* new_proc, struct thread* from_thread);
103
104int proc_die(proc_t* p);
105int proc_block_all_threads(proc_t* p, const struct blocker* blocker);
106
107/**
108 * PROC FD FUNCTIONS
109 */
110
111int proc_chdir(proc_t* p, const char* path);
112file_descriptor_t* proc_get_free_fd(proc_t* p);
113file_descriptor_t* proc_get_fd(proc_t* p, uint32_t index);
114int proc_get_fd_id(proc_t* proc, file_descriptor_t* fd);
115int proc_copy_fd(file_descriptor_t* oldfd, file_descriptor_t* newfd);
116
117/**
118 * PROC HELPER FUNCTIONS
119 */
120
121static ALWAYS_INLINE bool proc_is_su(proc_t* p) { return p->euid == 0; }
122static ALWAYS_INLINE int proc_is_alive(proc_t* p) { return p->status == PROC_ALIVE; }
123
124#endif // _KERNEL_TASKING_PROC_H