Kernel/LibC: add SYS_STAT and stat(), lstat()
This commit is contained in:
		
							parent
							
								
									30bb61a775
								
							
						
					
					
						commit
						9d64dbd5c2
					
				|  | @ -64,7 +64,7 @@ namespace Kernel | |||
| 		BAN::ErrorOr<off_t> tell(int fd); | ||||
| 
 | ||||
| 		BAN::ErrorOr<void> fstat(int fd, struct stat*); | ||||
| 		BAN::ErrorOr<void> stat(BAN::StringView path, struct stat*); | ||||
| 		BAN::ErrorOr<void> stat(BAN::StringView path, struct stat*, int flags); | ||||
| 
 | ||||
| 		BAN::ErrorOr<void> mount(BAN::StringView source, BAN::StringView target); | ||||
| 
 | ||||
|  |  | |||
|  | @ -522,9 +522,9 @@ namespace Kernel | |||
| 		return {}; | ||||
| 	} | ||||
| 
 | ||||
| 	BAN::ErrorOr<void> Process::stat(BAN::StringView path, struct stat* out) | ||||
| 	BAN::ErrorOr<void> Process::stat(BAN::StringView path, struct stat* out, int flags) | ||||
| 	{ | ||||
| 		int fd = TRY(open(path, O_RDONLY | O_NOFOLLOW)); | ||||
| 		int fd = TRY(open(path, flags)); | ||||
| 		auto ret = fstat(fd, out); | ||||
| 		MUST(close(fd)); | ||||
| 		return ret; | ||||
|  |  | |||
|  | @ -534,7 +534,7 @@ argument_done: | |||
| 				BAN::String entry_path; | ||||
| 				TRY(entry_path.append(entry_prefix)); | ||||
| 				TRY(entry_path.append(entry)); | ||||
| 				TRY(Process::current().stat(entry_path, &st)); | ||||
| 				TRY(Process::current().stat(entry_path, &st, O_RDONLY | O_NOFOLLOW)); | ||||
| 
 | ||||
| 				Inode::Mode mode { st.st_mode }; | ||||
| 
 | ||||
|  | @ -577,7 +577,7 @@ argument_done: | |||
| 			} | ||||
| 			 | ||||
| 			struct stat st; | ||||
| 			TRY(Process::current().stat(arguments[1], &st)); | ||||
| 			TRY(Process::current().stat(arguments[1], &st, O_RDONLY | O_NOFOLLOW)); | ||||
| 
 | ||||
| 			Inode::Mode mode { st.st_mode }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -128,6 +128,14 @@ namespace Kernel | |||
| 		return ret.value(); | ||||
| 	} | ||||
| 
 | ||||
| 	long sys_stat(const char* path, struct stat* buf, int flags) | ||||
| 	{ | ||||
| 		auto ret = Process::current().stat(path, buf, flags); | ||||
| 		if (ret.is_error()) | ||||
| 			return -ret.error().get_error_code(); | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	extern "C" long sys_fork_trampoline(); | ||||
| 
 | ||||
| 	extern "C" long cpp_syscall_handler(int syscall, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t arg4, uintptr_t arg5) | ||||
|  | @ -193,6 +201,9 @@ namespace Kernel | |||
| 		case SYS_WAIT: | ||||
| 			ret = sys_wait((pid_t)arg1, (int*)arg2, (int)arg3); | ||||
| 			break; | ||||
| 		case SYS_STAT: | ||||
| 			ret = sys_stat((const char*)arg1, (struct stat*)arg2, (int)arg3); | ||||
| 			break; | ||||
| 		default: | ||||
| 			Kernel::panic("Unknown syscall {}", syscall); | ||||
| 		} | ||||
|  |  | |||
|  | @ -180,8 +180,8 @@ static void init2(void* tty1) | |||
| 
 | ||||
| 	((TTY*)tty1)->initialize_device(); | ||||
| 
 | ||||
| 	//MUST(Process::create_userspace("/usr/bin/test"sv));
 | ||||
| 	//return;
 | ||||
| 	MUST(Process::create_userspace("/usr/bin/Shell"sv)); | ||||
| 	return; | ||||
| 
 | ||||
| 	Process::create_kernel( | ||||
| 		[](void*)  | ||||
|  |  | |||
|  | @ -10,6 +10,7 @@ set(LIBC_SOURCES | |||
| 	stdio.cpp | ||||
| 	stdlib.cpp | ||||
| 	string.cpp | ||||
| 	sys/stat.cpp | ||||
| 	sys/wait.cpp | ||||
| 	termios.cpp | ||||
| 	unistd.cpp | ||||
|  |  | |||
|  | @ -22,6 +22,7 @@ __BEGIN_DECLS | |||
| #define SYS_EXEC 15 | ||||
| #define SYS_REALLOC 16 | ||||
| #define SYS_WAIT 17 | ||||
| #define SYS_STAT 18 | ||||
| 
 | ||||
| __END_DECLS | ||||
| 
 | ||||
|  |  | |||
|  | @ -0,0 +1,14 @@ | |||
| #include <fcntl.h> | ||||
| #include <sys/stat.h> | ||||
| #include <sys/syscall.h> | ||||
| #include <unistd.h> | ||||
| 
 | ||||
| int lstat(const char* __restrict path, struct stat* __restrict buf) | ||||
| { | ||||
|     return syscall(SYS_STAT, path, buf, O_RDONLY | O_NOFOLLOW); | ||||
| } | ||||
| 
 | ||||
| int stat(const char* __restrict path, struct stat* __restrict buf) | ||||
| { | ||||
|     return syscall(SYS_STAT, path, buf, O_RDONLY); | ||||
| } | ||||
|  | @ -5,6 +5,7 @@ | |||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <sys/stat.h> | ||||
| #include <sys/syscall.h> | ||||
| #include <unistd.h> | ||||
| 
 | ||||
|  | @ -145,6 +146,14 @@ long syscall(long syscall, ...) | |||
| 			ret = Kernel::syscall(SYS_WAIT, pid, (uintptr_t)stat_loc, options); | ||||
| 			break; | ||||
| 		} | ||||
| 		case SYS_STAT: | ||||
| 		{ | ||||
| 			const char* path = va_arg(args, const char*); | ||||
| 			struct stat* buf = va_arg(args, struct stat*); | ||||
| 			int flags = va_arg(args, int); | ||||
| 			ret = Kernel::syscall(SYS_STAT, (uintptr_t)path, (uintptr_t)buf, flags); | ||||
| 			break; | ||||
| 		} | ||||
| 		default: | ||||
| 			puts("LibC: Unhandeled syscall"); | ||||
| 			ret = -ENOSYS; | ||||
|  |  | |||
|  | @ -1,6 +1,7 @@ | |||
| #include <BAN/ScopeGuard.h> | ||||
| #include <BAN/String.h> | ||||
| #include <BAN/Vector.h> | ||||
| #include <ctype.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <sys/stat.h> | ||||
|  | @ -42,6 +43,13 @@ int execute_command(BAN::StringView command) | |||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		struct stat stat_buf; | ||||
| 		if (stat(args.front(), &stat_buf) == -1) | ||||
| 		{ | ||||
| 			fprintf(stderr, "command not found: %s\n", args.front()); | ||||
| 			return 1; | ||||
| 		} | ||||
| 
 | ||||
| 		pid_t pid = fork(); | ||||
| 		if (pid == 0) | ||||
| 		{ | ||||
|  | @ -63,6 +71,28 @@ int execute_command(BAN::StringView command) | |||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| int prompt_length(BAN::StringView prompt) | ||||
| { | ||||
| 	int length { 0 }; | ||||
| 	bool in_escape { false }; | ||||
| 	for (char c : prompt) | ||||
| 	{ | ||||
| 		if (in_escape) | ||||
| 		{ | ||||
| 			if (isalpha(c)) | ||||
| 				in_escape = false; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			if (c == '\e') | ||||
| 				in_escape = true; | ||||
| 			else | ||||
| 				length++; | ||||
| 		} | ||||
| 	} | ||||
| 	return length; | ||||
| } | ||||
| 
 | ||||
| int main(int argc, char** argv) | ||||
| { | ||||
| 	tcgetattr(0, &old_termios); | ||||
|  | @ -102,8 +132,8 @@ int main(int argc, char** argv) | |||
| 			fread(&c, 1, sizeof(char), stdin); | ||||
| 			switch (c) | ||||
| 			{ | ||||
| 				case 'A': if (index > 0)					{ index--; col = buffers[index].size(); fprintf(stdout, "\e[G%s\e[K", buffers[index].data()); fflush(stdout); } break; | ||||
| 				case 'B': if (index < buffers.size() - 1)	{ index++; col = buffers[index].size(); fprintf(stdout, "\e[G%s\e[K", buffers[index].data()); fflush(stdout); } break; | ||||
| 				case 'A': if (index > 0)					{ index--; col = buffers[index].size(); fprintf(stdout, "\e[%dG%s\e[K", prompt_length(prompt) + 1, buffers[index].data()); fflush(stdout); } break; | ||||
| 				case 'B': if (index < buffers.size() - 1)	{ index++; col = buffers[index].size(); fprintf(stdout, "\e[%dG%s\e[K", prompt_length(prompt) + 1, buffers[index].data()); fflush(stdout); } break; | ||||
| 				case 'C': break; | ||||
| 				case 'D': break; | ||||
| 			} | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue