Skip to content

Commit e85aad7

Browse files
Implemented UNIX like streams (STDIN, STDOUT, STDERR) and ported the existing code.
1 parent ee1d2cb commit e85aad7

File tree

9 files changed

+128
-41
lines changed

9 files changed

+128
-41
lines changed

source/drivers/networking/ethernet/RTL/8139.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,7 @@ void rtl8139_init(struct rtl8139* nic) {
3434
// Initialize MAC address
3535
read_mac_address();
3636

37-
print("Mac Address: ");
38-
printf("%x:%x:%x:%x:%x:%x", nic->mac_address[0], nic->mac_address[1], nic->mac_address[2], nic->mac_address[3], nic->mac_address[4], nic->mac_address[5]);
37+
printf("Mac Address : %x:%x:%x:%x:%x:%x", nic->mac_address[0], nic->mac_address[1], nic->mac_address[2], nic->mac_address[3], nic->mac_address[4], nic->mac_address[5]);
3938

4039
// Enable receive and transmit
4140
outw(nic->io_base + RTL8139_REG_COMMAND, RTL8139_CMD_RX_ENABLE | RTL8139_CMD_TX_ENABLE);

source/includes/filesystems/vfs.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@
1111
#ifndef VFS_H
1212
#define VFS_H
1313

14-
#include <basics.h>
15-
#include <stdint.h>
14+
#include <graphics.h>
1615
#include <ahci.h>
1716
#include <filesystems/fat16.h>
1817

source/includes/graphics.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,15 @@
99
*
1010
*/
1111
#ifndef __GRAPHICS_H_
12-
#define __GRAPHICS_H_ 1
12+
#define __GRAPHICS_H_
1313

1414
#include <stdint.h>
1515
#include <stddef.h>
1616
#include <stdarg.h>
1717
#include <stdbool.h>
1818
#include <basics.h>
1919
#include <strings.h>
20+
#include <stream.h>
2021

2122
// ANSI color codes for text formatting
2223
#define reset_color "\033[37m"
@@ -39,6 +40,9 @@ extern bool enable_logging;
3940
#define printfnoln(fmt, ...) \
4041
printfnoln_internal(__FILE__, __func__, __LINE__, fmt, ##__VA_ARGS__)
4142

43+
#define eprintf(fmt, ...) \
44+
eprintf_internal(__FILE__, __func__, __LINE__, fmt, ##__VA_ARGS__)
45+
4246

4347
/**
4448
* @brief Display a warning message.
@@ -89,8 +93,6 @@ void done(cstring message, cstring file);
8993
*/
9094
void putc(char c);
9195

92-
93-
9496
/**
9597
* @brief Prints a value in binary format
9698
*
@@ -130,14 +132,15 @@ void printfnoln_internal(cstring file, cstring func, int64 line, cstring format,
130132
* The newline flag controls whether a newline character ('\n') is printed
131133
* automatically at the end of the output.
132134
*
135+
* @param stream The unix like STDOUT, STDERR.
133136
* @param file The source file name of the caller (for logging context)
134137
* @param func The function name of the caller (for logging context)
135138
* @param line The source line number of the call (for logging context)
136139
* @param newline If true, appends a newline at the end of the formatted output
137140
* @param format The printf-style format string
138141
* @param argp The variable argument list (already started via va_start)
139142
*/
140-
void vprintf_internal(cstring file, cstring func, int64 line, bool newline, cstring format, va_list argp);
143+
void vprintf_internal(stream_t stream, cstring file, cstring func, int64 line, bool newline, cstring format, va_list argp);
141144

142145
/**
143146
* @brief Formats a string into a buffer using a va_list.

source/includes/kernel.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
#include <image/targa.h>
4343
#include <executables/fwde.h>
4444
#include <fdlfcn.h>
45+
#include <stream.h>
4546

4647
/**
4748
* @brief Long story short: linker is a mole-rat and gives virtual addresses. But we asked the linker to allocate at this address, so we are spoofing its "security" to get the real memory address of kernel start and end.

source/includes/stream.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/**
2+
* @file stream.h
3+
* @author Pradosh ([email protected])
4+
* @brief Unix like standard streams.
5+
* @version 0.1
6+
* @date 2026-01-03
7+
*
8+
* @copyright Copyright (c) Pradosh 2026
9+
*
10+
*/
11+
#ifndef STREAM_H
12+
#define STREAM_H
13+
14+
#include <stddef.h>
15+
16+
typedef enum {
17+
STDIN = 0,
18+
STDOUT = 1,
19+
STDERR = 2
20+
} stream_t;
21+
22+
void stream_init(void);
23+
24+
/**
25+
* @brief Redirect output to a file.
26+
*
27+
* @param s the stream type.
28+
* @param file If file is 'null' then output will be in terminal.
29+
*/
30+
// void stream_set_file(stream_t s, vfs_file_t* file);
31+
32+
33+
void stream_write(stream_t s, const char* buf, size_t len);
34+
35+
36+
void stream_putc(stream_t s, char c);
37+
38+
#endif

source/kernel/C/cpuid.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ void print_L1_cache_info() {
8181
int32 eax, ebx, ecx, edx;
8282
cpuid(0x80000006, &eax, &ebx, &ecx, &edx);
8383
if ((edx & 0xFF) == 0) {
84-
print("L1 Cache not present.\n");
84+
printf("L1 Cache not present.");
8585
return;
8686
}
8787
printf("CPU Line Size: %d B, Assoc. Type: %d; Cache Size: %d KB. (L1 INFO)", ecx & 0xff, (ecx >> 12) & 0x07, (ecx >> 16) & 0xffff);
@@ -94,7 +94,7 @@ void print_L2_cache_info() {
9494
int32 eax, ebx, ecx, edx;
9595
cpuid(0x80000006, &eax, &ebx, &ecx, &edx);
9696
if ((edx & 0xFF) == 0) {
97-
print("L2 Cache not present.\n");
97+
printf("L2 Cache not present.");
9898
return;
9999
}
100100
printf("CPU Line Size: %d B, Assoc. Type: %d; Cache Size: %d KB. (L2 INFO)", ecx & 0xff, (ecx >> 12) & 0x0F, (ecx >> 16) & 0xFFFF);
@@ -107,7 +107,7 @@ void print_L3_cache_info() {
107107
int32 eax, ebx, ecx, edx;
108108
cpuid(0x80000006, &eax, &ebx, &ecx, &edx);
109109
if ((edx & 0xFF) == 0) {
110-
print("L3 Cache not present.\n");
110+
printf("L3 Cache not present.");
111111
return;
112112
}
113113
printf("CPU Line Size: %d B, Assoc. Type: %d; Cache Size: %d KB. (L3 INFO)", edx & 0xff, (edx >> 12) & 0x0F, (edx >> 16) & 0xFFFF);

source/kernel/C/kernel.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ void main(void) {
120120
hcf2();
121121
}
122122

123+
stream_init();
123124
// Fetch the first framebuffer.
124125
framebuffer = framebuffer_request.response->framebuffers[0];
125126

@@ -186,8 +187,7 @@ void main(void) {
186187

187188
probe_pci();
188189

189-
print(public_key);
190-
print("\n");
190+
printf(public_key);
191191

192192
printf("Display Resolution: %dx%d (%d) pixels. Pitch: %d", framebuffer->width, framebuffer->height, framebuffer->width*framebuffer->height, framebuffer->pitch);
193193

@@ -244,7 +244,7 @@ void main(void) {
244244
}
245245

246246
/**
247-
* @brief The basic print function.
247+
* @brief The basic raw print function. (DO NOT HANDLE STREAMS)
248248
*
249249
* @param msg The message to be printed
250250
*/

source/kernel/C/logger.c

Lines changed: 18 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
static const char hex_digits[] = "0123456789abcdef";
1515
static const char caps_hex_digits[] = "0123456789ABCDEF";
16+
static stream_t printf_stream;
1617

1718
string last_filename = "unknown"; // for warn, info, err, done
1819
string last_print_file = "unknown";
@@ -31,11 +32,7 @@ bool enable_logging = true;
3132
*/
3233
void warn(cstring message, cstring file) {
3334
cstring warn_message = yellow_color "[***] → " reset_color;
34-
print(warn_message);
35-
print(message);
36-
print(" at " blue_color);
37-
print(file);
38-
print(reset_color "\n");
35+
printf("%s%s at " blue_color "%s" reset_color, warn_message, message, file);
3936

4037
debug_print(warn_message);
4138
debug_print(message);
@@ -56,11 +53,7 @@ void warn(cstring message, cstring file) {
5653
*/
5754
void error(cstring message, cstring file) {
5855
cstring err_message = red_color "[***] → " reset_color;
59-
print(err_message);
60-
print(message);
61-
print(" at " blue_color);
62-
print(file);
63-
print(reset_color "\n");
56+
eprintf("%s%s at " blue_color "%s" reset_color, err_message, message, file);
6457

6558
debug_print(err_message);
6659
debug_print(message);
@@ -81,11 +74,7 @@ void error(cstring message, cstring file) {
8174
*/
8275
void info(cstring message, cstring file) {
8376
cstring info_message = blue_color "[***] → " reset_color;
84-
print(info_message);
85-
print(message);
86-
print(" at " blue_color);
87-
print(file);
88-
print(reset_color "\n");
77+
printf("%s%s at " blue_color "%s" reset_color, info_message, message, file);
8978

9079
debug_print(info_message);
9180
debug_print(message);
@@ -106,11 +95,7 @@ void info(cstring message, cstring file) {
10695
*/
10796
void done(cstring message, cstring file) {
10897
cstring done_message = green_color "[***] → " reset_color;
109-
print(done_message);
110-
print(message);
111-
print(" at " blue_color);
112-
print(file);
113-
print(reset_color "\n");
98+
printf("%s%s at " blue_color "%s" reset_color, done_message, message, file);
11499

115100
debug_print(done_message);
116101
debug_print(message);
@@ -128,10 +113,7 @@ void done(cstring message, cstring file) {
128113
* @note Internally using Flanterm's putchar function
129114
*/
130115
void vputc(char c) {
131-
char str[2];
132-
str[0] = c;
133-
str[1] = '\0';
134-
print(str);
116+
stream_putc(printf_stream, c);
135117
}
136118

137119
void printdec_fmt(int num, int width, bool zero_pad)
@@ -250,13 +232,15 @@ static void printstr_fmt(const char* s, int width)
250232
}
251233

252234

253-
void vprintf_internal(cstring file, cstring func, int64 line, bool newline, cstring format, va_list argp) {
235+
void vprintf_internal(stream_t stream, cstring file, cstring func, int64 line, bool newline, cstring format, va_list argp) {
254236
if (enable_logging) {
255237
last_print_file = file;
256238
last_print_func = func;
257239
last_print_line = line;
258240
}
259241

242+
printf_stream = stream;
243+
260244
while (*format != '\0') {
261245
if (*format == '%') {
262246
format++;
@@ -331,14 +315,21 @@ void vprintf_internal(cstring file, cstring func, int64 line, bool newline, cstr
331315
void printf_internal(cstring file, cstring func, int64 line, cstring format, ...) {
332316
va_list argp;
333317
va_start(argp, format);
334-
vprintf_internal(file, func, line, true, format, argp);
318+
vprintf_internal(STDOUT, file, func, line, true, format, argp);
335319
va_end(argp);
336320
}
337321

338322
void printfnoln_internal(cstring file, cstring func, int64 line, cstring format, ...) {
339323
va_list argp;
340324
va_start(argp, format);
341-
vprintf_internal(file, func, line, false, format, argp);
325+
vprintf_internal(STDOUT, file, func, line, false, format, argp);
326+
va_end(argp);
327+
}
328+
329+
void eprintf_internal(cstring file, cstring func, int64 line, cstring format, ...) {
330+
va_list argp;
331+
va_start(argp, format);
332+
vprintf_internal(STDERR, file, func, line, true, format, argp);
342333
va_end(argp);
343334
}
344335

source/kernel/C/stream.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/**
2+
* @file stream.c
3+
* @author Pradosh ([email protected])
4+
* @brief Unix like standard streams.
5+
* @version 0.1
6+
* @date 2026-01-03
7+
*
8+
* @copyright Copyright (c) Pradosh 2026
9+
*
10+
*/
11+
12+
#include <stream.h>
13+
#include <graphics.h> // flanterm
14+
#include <basics.h>
15+
#include <filesystems/vfs.h>
16+
17+
extern struct flanterm_context* ft_ctx;
18+
19+
typedef struct {
20+
vfs_file_t* file; // NULL → terminal
21+
} stream_impl_t;
22+
23+
static stream_impl_t streams[3];
24+
25+
void stream_init(void)
26+
{
27+
streams[STDIN].file = NULL;
28+
streams[STDOUT].file = NULL;
29+
streams[STDERR].file = NULL;
30+
}
31+
32+
void stream_set_file(stream_t s, vfs_file_t* file)
33+
{
34+
streams[s].file = file;
35+
}
36+
37+
void stream_write(stream_t s, const char* buf, size_t len)
38+
{
39+
if (!buf || len == 0) return;
40+
41+
stream_impl_t* st = &streams[s];
42+
43+
if (st->file) {
44+
vfs_write(st->file, (const uint8_t*)buf, len);
45+
} else {
46+
flanterm_write(ft_ctx, buf, len);
47+
}
48+
}
49+
50+
void stream_putc(stream_t s, char c)
51+
{
52+
char str[2];
53+
str[0] = c;
54+
str[1] = '\0';
55+
stream_write(s, str, 1);
56+
}

0 commit comments

Comments
 (0)