Kernel/BAN: move unix time conversion to BAN and add stat to Shell
This commit is contained in:
		
							parent
							
								
									770f7716a0
								
							
						
					
					
						commit
						f8a2c60c8d
					
				|  | @ -0,0 +1,71 @@ | |||
| #include <BAN/Time.h> | ||||
| 
 | ||||
| namespace BAN | ||||
| { | ||||
| 
 | ||||
| 	static constexpr bool is_leap_year(uint64_t year) | ||||
| 	{ | ||||
| 		if (year % 400 == 0) | ||||
| 			return true; | ||||
| 		if (year % 100 == 0) | ||||
| 			return false; | ||||
| 		if (year % 4 == 0) | ||||
| 			return true; | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	static constexpr uint64_t leap_days_since_epoch(const BAN::Time& time) | ||||
| 	{ | ||||
| 		uint64_t leap_years = 0; | ||||
| 		for (uint32_t year = 1970; year < time.year; year++) | ||||
| 			if (is_leap_year(year)) | ||||
| 				leap_years++; | ||||
| 		if (is_leap_year(time.year) && time.month >= 3) | ||||
| 			leap_years++; | ||||
| 		return leap_years; | ||||
| 	} | ||||
| 	 | ||||
| 	static constexpr uint64_t month_days[] { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; | ||||
| 
 | ||||
| 	uint64_t to_unix_time(const BAN::Time& time) | ||||
| 	{ | ||||
| 		uint64_t years = time.year - 1970; | ||||
| 		uint64_t days = years * 365 + month_days[time.month - 1] + leap_days_since_epoch(time) + (time.day - 1); | ||||
| 		uint64_t hours = days * 24 + time.hour; | ||||
| 		uint64_t minutes = hours * 60 + time.minute; | ||||
| 		uint64_t seconds = minutes * 60 + time.second; | ||||
| 		return seconds; | ||||
| 	} | ||||
| 
 | ||||
| 	BAN::Time from_unix_time(uint64_t unix_time) | ||||
| 	{		 | ||||
| 		BAN::Time time {}; | ||||
| 
 | ||||
| 		time.second = unix_time % 60; unix_time /= 60; | ||||
| 		time.minute = unix_time % 60; unix_time /= 60; | ||||
| 		time.hour   = unix_time % 24; unix_time /= 24; | ||||
| 
 | ||||
| 		uint64_t total_days = unix_time; | ||||
| 
 | ||||
| 		time.week_day = (total_days + 4) % 7 + 1; | ||||
| 
 | ||||
| 		time.year = 1970; | ||||
| 		while (total_days >= 365U + is_leap_year(time.year)) | ||||
| 		{ | ||||
| 			total_days -= 365U + is_leap_year(time.year); | ||||
| 			time.year++; | ||||
| 		} | ||||
| 
 | ||||
| 		bool is_leap_day = is_leap_year(time.year) && total_days == month_days[2]; | ||||
| 		bool had_leap_day = is_leap_year(time.year) && total_days > month_days[2]; | ||||
| 
 | ||||
| 		for (time.month = 1; time.month < 12; time.month++) | ||||
| 			if (total_days < month_days[time.month] + (is_leap_day || had_leap_day)) | ||||
| 				break; | ||||
| 
 | ||||
| 		time.day = total_days - month_days[time.month - 1] + !had_leap_day; | ||||
| 
 | ||||
| 		return time; | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
|  | @ -34,6 +34,7 @@ $(ARCH_FREEOBJS)	\ | |||
| BAN/Memory.o		\ | ||||
| BAN/String.o		\ | ||||
| BAN/StringView.o	\ | ||||
| BAN/Time.o			\ | ||||
|   | ||||
| HOSTEDOBJS=\
 | ||||
| $(ARCH_HOSTEDOBJS) \ | ||||
|  |  | |||
|  | @ -9,15 +9,18 @@ namespace BAN | |||
| 
 | ||||
| 	struct Time | ||||
| 	{ | ||||
| 		uint8_t	second; | ||||
| 		uint8_t	minute; | ||||
| 		uint8_t	hour; | ||||
| 		uint8_t week_day; | ||||
| 		uint8_t	day; | ||||
| 		uint32_t year; | ||||
| 		uint8_t	month; | ||||
| 		int		year; | ||||
| 		uint8_t	day; | ||||
| 		uint8_t	hour; | ||||
| 		uint8_t	minute; | ||||
| 		uint8_t	second; | ||||
| 		uint8_t week_day; | ||||
| 	}; | ||||
| 
 | ||||
| 	uint64_t to_unix_time(const BAN::Time&); | ||||
| 	BAN::Time from_unix_time(uint64_t); | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| namespace BAN::Formatter | ||||
|  |  | |||
|  | @ -6,6 +6,5 @@ namespace RTC | |||
| { | ||||
| 
 | ||||
| 	BAN::Time get_current_time(); | ||||
| 	uint64_t get_unix_time(); | ||||
| 
 | ||||
| } | ||||
|  | @ -334,7 +334,7 @@ namespace Kernel | |||
| 		if (error_or.error().get_error_code() != ENOENT) | ||||
| 			return error_or.error(); | ||||
| 
 | ||||
| 		uint64_t current_time = RTC::get_unix_time(); | ||||
| 		uint64_t current_time = BAN::to_unix_time(RTC::get_current_time()); | ||||
| 
 | ||||
| 		Ext2::Inode ext2_inode; | ||||
| 		ext2_inode.mode			= mode; | ||||
|  |  | |||
|  | @ -87,41 +87,4 @@ namespace RTC | |||
| 		return time; | ||||
| 	} | ||||
| 
 | ||||
| 	static bool is_leap_year(uint64_t year) | ||||
| 	{ | ||||
| 		if (year % 400 == 0) | ||||
| 			return true; | ||||
| 		if (year % 100 == 0) | ||||
| 			return false; | ||||
| 		if (year % 4 == 0) | ||||
| 			return true; | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	static uint64_t leap_days_since_epoch(const BAN::Time& time) | ||||
| 	{ | ||||
| 		uint64_t leap_years = 0; | ||||
| 		for (int year = 1970; year < time.year; year++) | ||||
| 			if (is_leap_year(year)) | ||||
| 				leap_years++; | ||||
| 		if (is_leap_year(time.year)) | ||||
| 			if (time.month >= 3 || (time.month == 2 && time.day == 29)) | ||||
| 				leap_years++; | ||||
| 		return leap_years; | ||||
| 	} | ||||
| 
 | ||||
| 	uint64_t get_unix_time() | ||||
| 	{ | ||||
| 		auto time = get_current_time(); | ||||
| 
 | ||||
| 		uint64_t month_days[] { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; | ||||
| 
 | ||||
| 		uint64_t years = time.year - 1970; | ||||
| 		uint64_t days = years * 365 + month_days[time.month - 1] + time.day + leap_days_since_epoch(time) - 1; | ||||
| 		uint64_t hours = days * 24 + time.hour; | ||||
| 		uint64_t minutes = hours * 60 + time.minute; | ||||
| 		uint64_t seconds = minutes * 60 + time.second; | ||||
| 		return seconds; | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
|  | @ -425,6 +425,43 @@ argument_done: | |||
| 			} | ||||
| 			TTY_PRINTLN(""); | ||||
| 		} | ||||
| 		else if (arguments.front() == "stat") | ||||
| 		{ | ||||
| 			if (arguments.size() != 2) | ||||
| 				return BAN::Error::from_c_string("usage: 'stat path'"); | ||||
| 			 | ||||
| 			stat st; | ||||
| 			TRY(Process::current()->stat(arguments[1], &st)); | ||||
| 
 | ||||
| 			auto mode_string = [](mode_t mode) | ||||
| 			{ | ||||
| 				static char buffer[11] {}; | ||||
| 				buffer[0] = (mode & Inode::Mode::IFDIR) ? 'd' : '-'; | ||||
| 				buffer[1] = (mode & Inode::Mode::IRUSR) ? 'r' : '-'; | ||||
| 				buffer[2] = (mode & Inode::Mode::IWUSR) ? 'w' : '-'; | ||||
| 				buffer[3] = (mode & Inode::Mode::IXUSR) ? 'x' : '-'; | ||||
| 				buffer[4] = (mode & Inode::Mode::IRGRP) ? 'r' : '-'; | ||||
| 				buffer[5] = (mode & Inode::Mode::IWGRP) ? 'w' : '-'; | ||||
| 				buffer[6] = (mode & Inode::Mode::IXGRP) ? 'x' : '-'; | ||||
| 				buffer[7] = (mode & Inode::Mode::IROTH) ? 'r' : '-'; | ||||
| 				buffer[8] = (mode & Inode::Mode::IWOTH) ? 'w' : '-'; | ||||
| 				buffer[9] = (mode & Inode::Mode::IXOTH) ? 'x' : '-'; | ||||
| 				return (const char*)buffer; | ||||
| 			}; | ||||
| 
 | ||||
| 			const char* type = | ||||
| 				(st.st_mode & Inode::Mode::IFREG) ? "regular file" : | ||||
| 				(st.st_mode & Inode::Mode::IFDIR) ? "directory" : | ||||
| 													"other"; | ||||
| 			 | ||||
| 			TTY_PRINTLN("  File: {}", arguments[1]); | ||||
| 			TTY_PRINTLN("  Size: {}\tBlocks: {}\tIO Block: {}\t {}", st.st_size, st.st_blocks, st.st_blksize, type); | ||||
| 			TTY_PRINTLN("Device: {},{}\tInode: {}\tLinks: {}", st.st_dev, st.st_rdev, st.st_ino, st.st_nlink); | ||||
| 			TTY_PRINTLN("Access: ({}/{})\tUid: {}\tGid: {}", st.st_mode, mode_string(st.st_mode), st.st_uid, st.st_gid); | ||||
| 			TTY_PRINTLN("Access: {}", BAN::from_unix_time(st.st_atime)); | ||||
| 			TTY_PRINTLN("Modify: {}", BAN::from_unix_time(st.st_mtime)); | ||||
| 			TTY_PRINTLN("Change: {}", BAN::from_unix_time(st.st_ctime)); | ||||
| 		} | ||||
| 		else if (arguments.front() == "cd") | ||||
| 		{ | ||||
| 			if (arguments.size() > 2) | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue