#include "int.h" #include "sys.h" #define print(str) write(STDOUT, str, (sizeof str) - 1) void printhex(uint64_t num) { char msg[17] = {' '}; msg[16] = '\n'; for (int i = 0; i < 16; ++i) { char nibble = (num >> ((15 - i) * 4)) & 0xf; char c; if (nibble > 9) { c = nibble + '7'; } else { c = nibble + '0'; } msg[i] = c; } write(STDOUT, msg, 17); } int main(int argc, char* argv[]) { // Test the write syscall intptr_t n = write(STDOUT, "Hello\n", 6); if(n != 6) return n; // Test argc for(int i = 0; i < argc; ++i){ int len = strlen(argv[i]); write(STDOUT, argv[i], len); write(STDOUT, "\n", 1); } // Test the fork syscall uint64_t pid = fork(); // Print the pid in hex printhex(pid); // Child process if (pid == 0) { const char *progname = "/bin/sh"; const char *argv[4] = { progname, "-c", "echo hi from sh", 0, }; const char **envp = {0}; int32_t err = execve(progname, argv, envp); // return with error code if execve fails return err; } int status; // Note: this is not JUST the exit code of the child waitpid(pid, &status, 0); print("Child wstatus: "); printhex((uint64_t)status); // Test the read syscall #define INPUT_BUFFER_LEN 4096 char input_buffer[INPUT_BUFFER_LEN] = {0}; int32_t fout = openc("outfile", O_RDWR | O_CREAT | O_TRUNC, 0664); print("Enter some text:"); intptr_t n_read = read(STDIN, input_buffer, INPUT_BUFFER_LEN); write(STDOUT, input_buffer, n_read); if(fout > 0) { write(fout, input_buffer, n_read); fsync(fout); close(fout); } // Test the open syscall int32_t file = open("/proc/version", O_RDONLY); if (file > 0) { int i = read(file, input_buffer, INPUT_BUFFER_LEN); while(i > 0) { write(STDOUT, input_buffer, i); i = read(file, input_buffer, INPUT_BUFFER_LEN); } } else { print("Could not open /proc/version\n"); } // Test sleep print("Sleeping for 5 secs\n"); struct timespec sleeptime; sleeptime.tv_sec = 5; while (nanosleep(&sleeptime, &sleeptime) != 0) {} print("DONE\n"); return 69; }