summaryrefslogtreecommitdiff
path: root/os.h
blob: 37b71285a7b8c2bf6f3ebadc78966b9b7c3305ce (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// a bunch of OS-dependent functions
#ifndef OS_H_
#define OS_H_

typedef enum {
	FS_NON_EXISTENT,
	FS_FILE,
	FS_DIRECTORY,
	FS_OTHER
} FsType;

enum {
	FS_PERMISSION_READ = 0x01,
	FS_PERMISSION_WRITE = 0x02,
};
typedef u8 FsPermission;

typedef struct {
	FsType type;
	char name[];
} FsDirectoryEntry;

// returns what kind of thing this is.
FsType fs_path_type(const char *path);
FsPermission fs_path_permission(const char *path);
// Does this file exist? Returns false for directories.
bool fs_file_exists(const char *path);
// Returns a NULL-terminated array of the files/directories in this directory, or NULL if the directory does not exist/out of memory.
// When you're done with the entries, call fs_dir_entries_free (or call free on each entry, then on the whole array).
// NOTE: The files/directories aren't returned in any particular order!
FsDirectoryEntry **fs_list_directory(const char *dirname);
// Create the directory specified by `path`
// Returns:
// 1  if the directory was created successfully
// 0  if the directory already exists
// -1 if the path already exists, but it's not a directory, or if there's another error (e.g. don't have permission to create directory).
int fs_mkdir(const char *path);
// Puts the current working directory into buf, including a null-terminator, writing at most buflen bytes.
// Returns:
// 1  if the working directory was inserted into buf successfully
// 0  if buf is too short to hold the cwd
// -1 if we can't get the cwd for whatever reason.
int fs_get_cwd(char *buf, size_t buflen);
struct timespec time_last_modified(const char *filename);
struct timespec time_get(void);
// sleep for a certain number of nanoseconds
void time_sleep_ns(u64 ns);


// free the entries generated by fs_list_directory.
static void fs_dir_entries_free(FsDirectoryEntry **entries) {
	for (int i = 0; entries[i]; ++i)
		free(entries[i]);
	free(entries);
}

static double time_get_seconds(void) {
	return timespec_to_seconds(time_get());
}



// sleep for microseconds
static void time_sleep_us(u64 us) {
	time_sleep_ns(us * 1000);
}

// sleep for milliseconds
static void time_sleep_ms(u64 ms) {
	time_sleep_ns(ms * 1000000);
}

// sleep for seconds
static void time_sleep_s(u64 s) {
	time_sleep_ns(s * 1000000000);
}


typedef struct Process Process;

// zero everything except what you're using
typedef struct {
	bool stdin_blocking;
	bool stdout_blocking;
	bool separate_stderr;
	bool stderr_blocking; // not applicable if separate_stderr is false.
	const char *working_directory;
} ProcessSettings;

// get process ID of this process
int process_get_id(void);
// execute the given command (like if it was passed to system()), creating a new Process object.
// returns a valid process object on failure, but it will have an error, according to process_geterr
Process *process_run_ex(const char *command, const ProcessSettings *props);
// like process_run_ex, but with the default settings
Process *process_run(const char *command);
// returns the error last error produced, or NULL if there was no error.
const char *process_geterr(Process *process);
// write to stdin
// returns:
// -2 on error
// or a non-negative number indicating the number of bytes written.
long long process_write(Process *process, const char *data, size_t size);
// read from stdout+stderr
// returns:
// -2 on error
// -1 if no data is available right now
// 0 on end of file
// or a positive number indicating the number of bytes read to data (at most size)
long long process_read(Process *process, char *data, size_t size);
// like process_read, but reads stderr.
// this function ALWAYS RETURNS -2 if separate_stderr is not specified in the ProcessSettings.
//   if separate_stderr is false, then both stdout and stderr will be sent via process_read.
long long process_read_stderr(Process *process, char *data, size_t size);
// Checks if the process has exited. Returns:
// -1 if the process returned a non-zero exit code, or got a signal.
// 1  if the process exited successfully
// 0  if the process hasn't exited.
// If message is not NULL, it will be set to a description of what happened (e.g. "exited successfully")
int process_check_status(Process *process, char *message, size_t message_size);
// kills process if still running
// this also frees any resources used by `process`.
void process_kill(Process *process);

#endif // OS_H_