PatchworkOS
Loading...
Searching...
No Matches
main.c
Go to the documentation of this file.
1#define __STDC_WANT_LIB_EXT1__ 1
2#include <errno.h>
3#include <stdbool.h>
4#include <stdint.h>
5#include <stdio.h>
6#include <stdlib.h>
7#include <string.h>
8#include <sys/io.h>
9
11{
12 uint32_t terminalWidth = 80;
13 printf("\033[999C\033[6n");
15 char buffer[MAX_NAME] = {0};
16 for (uint32_t i = 0; i < sizeof(buffer) - 1; i++)
17 {
18 read(STDIN_FILENO, &buffer[i], 1);
19 if (buffer[i] == 'R')
20 {
21 break;
22 }
23 }
24 int row;
25 int cols;
26 sscanf(buffer, "\033[%d;%dR", &row, &cols);
27
28 if (cols != 0)
29 {
30 terminalWidth = (uint32_t)cols;
31 }
32
33 printf("\r");
35 return terminalWidth;
36}
37
38static uint64_t print_dir(const char* path)
39{
40 fd_t fd = openf("%s:dir", path);
41 if (fd == ERR)
42 {
43 fprintf(stderr, "ls: can't open directory %s (%s)\n", path, strerror(errno));
44 return ERR;
45 }
46
49 uint64_t bufferSize = 64;
50 entries = (dirent_t*)malloc(sizeof(dirent_t) * bufferSize);
51 if (entries == NULL)
52 {
53 close(fd);
54 fprintf(stderr, "ls: memory allocation failed\n");
55 return ERR;
56 }
57
58 uint64_t bytesRead;
59 while ((bytesRead = getdents(fd, &entries[entryCount], sizeof(dirent_t) * (bufferSize - entryCount))) > 0)
60 {
61 if (bytesRead == ERR)
62 {
63 close(fd);
65 fprintf(stderr, "ls: can't read directory %s (%s)\n", path, strerror(errno));
66 return ERR;
67 }
68 entryCount += bytesRead / sizeof(dirent_t);
69 if (entryCount >= bufferSize)
70 {
71 bufferSize *= 2;
72 dirent_t* newEntries = (dirent_t*)realloc(entries, sizeof(dirent_t) * bufferSize);
73 if (newEntries == NULL)
74 {
75 close(fd);
77 fprintf(stderr, "ls: re-allocation failed\n");
78 return ERR;
79 }
80 entries = newEntries;
81 }
82 }
83 close(fd);
84
85 if (entryCount == 0)
86 {
88 return 0;
89 }
90
91 uint64_t maxLength = 0;
92 for (uint64_t i = 0; i < entryCount; i++)
93 {
94 uint64_t nameLength = strlen(entries[i].name) + (entries[i].type == INODE_DIR ? 1 : 0);
95 if (nameLength > maxLength)
96 {
97 maxLength = nameLength;
98 }
99 }
100
101 uint32_t terminalWidth = terminal_columns_get();
102 uint32_t columnWidth = maxLength + 2;
103 if (columnWidth > terminalWidth)
104 {
105 columnWidth = terminalWidth;
106 }
107 uint32_t numColumns = terminalWidth / columnWidth;
108 if (numColumns == 0)
109 {
110 numColumns = 1;
111 }
112
113 uint32_t numRows = (entryCount + numColumns - 1) / numColumns;
114
115 for (uint32_t row = 0; row < numRows; row++)
116 {
117 for (uint32_t col = 0; col < numColumns; col++)
118 {
119 uint64_t index = col * numRows + row;
120 if (index < entryCount)
121 {
122 const char* name = entries[index].name;
123 bool isDir = entries[index].type == INODE_DIR;
124
125 if (isDir)
126 {
127 printf("\033[34m%s\033[0m/%-*s", name, columnWidth - (int)strlen(name) - 1, "");
128 }
129 else
130 {
131 printf("%-*s", columnWidth, name);
132 }
133 }
134 }
135 printf("\n");
136 }
137
138 free(entries);
139 return 0;
140}
141
142uint32_t main(uint32_t argc, char** argv)
143{
144 if (argc <= 1)
145 {
146 if (print_dir(".") == ERR)
147 {
148 return EXIT_FAILURE;
149 }
150 }
151 else
152 {
153 for (uint32_t i = 1; i < argc; i++)
154 {
155 if (print_dir(argv[i]) == ERR)
156 {
157 return EXIT_FAILURE;
158 }
159 }
160 }
161
162 return EXIT_SUCCESS;
163}
#define MAX_NAME
Maximum length of names.
Definition MAX_NAME.h:11
#define errno
Error number variable.
Definition errno.h:27
uint64_t getdents(fd_t fd, dirent_t *buffer, uint64_t count)
System call for reading directory entires.
Definition getdents.c:9
uint64_t close(fd_t fd)
System call for closing files.
Definition close.c:9
fd_t openf(const char *_RESTRICT format,...)
Wrapper for opening files with a formatted path.
Definition openf.c:9
uint64_t read(fd_t fd, void *buffer, uint64_t count)
System call for reading from files.
Definition read.c:9
#define STDIN_FILENO
Definition io.h:44
@ INODE_DIR
Is a directory.
Definition io.h:346
#define NULL
Pointer error value.
Definition NULL.h:23
__UINT64_TYPE__ fd_t
A file descriptor.
Definition fd_t.h:12
EFI_PHYSICAL_ADDRESS buffer
Definition mem.c:15
static uint64_t entryCount
Definition pci_config.c:7
#define ERR
Definition main.c:44
int main()
Definition main.c:97
static uint64_t terminal_columns_get(void)
Definition main.c:10
static uint64_t print_dir(const char *path)
Definition main.c:38
static start_entry_t entries[START_ENTRY_MAX]
Definition start_menu.c:21
__UINT32_TYPE__ uint32_t
Definition stdint.h:15
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
_PUBLIC int sscanf(const char *_RESTRICT s, const char *_RESTRICT format,...)
Definition sscanf.c:4
_PUBLIC int fflush(FILE *stream)
Definition fflush.c:6
_PUBLIC int printf(const char *_RESTRICT format,...)
Definition printf.c:5
FILE * stdout
Definition std_streams.c:17
FILE * stderr
Definition std_streams.c:18
_PUBLIC int fprintf(FILE *_RESTRICT stream, const char *_RESTRICT format,...)
Definition fprintf.c:5
_PUBLIC void * realloc(void *ptr, size_t size)
Definition realloc.c:13
#define EXIT_SUCCESS
Definition stdlib.h:46
#define EXIT_FAILURE
Definition stdlib.h:47
_PUBLIC void * malloc(size_t size)
Definition malloc.c:5
_PUBLIC void free(void *ptr)
Definition free.c:11
_PUBLIC char * strerror(int errnum)
Definition strerror.c:6
_PUBLIC size_t strlen(const char *s)
Definition strlen.c:3
Directory entry struct.
Definition io.h:424
const char * name
Definition start_menu.c:16