forked from PoliEcho-holding-org/kern
The printk(), panic() and kernel.h update
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
#include <ctype.h>
|
||||
|
||||
const unsigned char _CTYPE_TABLE[256] = {
|
||||
// Control characters (ASCII 0-31)
|
||||
_CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, // 0-7
|
||||
_CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, // 8-15
|
||||
_CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, // 16-23
|
||||
_CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, // 24-31
|
||||
// Space (ASCII 32)
|
||||
_SPACE_MASK | _PRINT_MASK,
|
||||
// Punctuation (ASCII 33-47)
|
||||
_PUNCT_MASK | _PRINT_MASK, // '!' (ASCII 33)
|
||||
_PUNCT_MASK | _PRINT_MASK, // '"' (ASCII 34)
|
||||
_PUNCT_MASK | _PRINT_MASK, // '#' (ASCII 35)
|
||||
_PUNCT_MASK | _PRINT_MASK, // '$' (ASCII 36)
|
||||
_PUNCT_MASK | _PRINT_MASK, // '%' (ASCII 37)
|
||||
_PUNCT_MASK | _PRINT_MASK, // '&' (ASCII 38)
|
||||
_PUNCT_MASK | _PRINT_MASK, // '\'' (ASCII 39)
|
||||
_PUNCT_MASK | _PRINT_MASK, // '(' (ASCII 40)
|
||||
_PUNCT_MASK | _PRINT_MASK, // ')' (ASCII 41)
|
||||
_PUNCT_MASK | _PRINT_MASK, // '*' (ASCII 42)
|
||||
_PUNCT_MASK | _PRINT_MASK, // '+' (ASCII 43)
|
||||
_PUNCT_MASK | _PRINT_MASK, // ',' (ASCII 44)
|
||||
_PUNCT_MASK | _PRINT_MASK, // '-' (ASCII 45)
|
||||
_PUNCT_MASK | _PRINT_MASK, // '.' (ASCII 46)
|
||||
_PUNCT_MASK | _PRINT_MASK, // '/' (ASCII 47)
|
||||
// Digits (ASCII 48-57)
|
||||
_DIGIT_MASK | _PRINT_MASK, // '0' (ASCII 48)
|
||||
_DIGIT_MASK | _PRINT_MASK, // '1' (ASCII 49)
|
||||
_DIGIT_MASK | _PRINT_MASK, // '2' (ASCII 50)
|
||||
_DIGIT_MASK | _PRINT_MASK, // '3' (ASCII 51)
|
||||
_DIGIT_MASK | _PRINT_MASK, // '4' (ASCII 52)
|
||||
_DIGIT_MASK | _PRINT_MASK, // '5' (ASCII 53)
|
||||
_DIGIT_MASK | _PRINT_MASK, // '6' (ASCII 54)
|
||||
_DIGIT_MASK | _PRINT_MASK, // '7' (ASCII 55)
|
||||
_DIGIT_MASK | _PRINT_MASK, // '8' (ASCII 56)
|
||||
_DIGIT_MASK | _PRINT_MASK, // '9' (ASCII 57)
|
||||
// Punctuation (ASCII 58-64)
|
||||
_PUNCT_MASK | _PRINT_MASK, // ':' (ASCII 58)
|
||||
_PUNCT_MASK | _PRINT_MASK, // ';' (ASCII 59)
|
||||
_PUNCT_MASK | _PRINT_MASK, // '<' (ASCII 60)
|
||||
_PUNCT_MASK | _PRINT_MASK, // '=' (ASCII 61)
|
||||
_PUNCT_MASK | _PRINT_MASK, // '>' (ASCII 62)
|
||||
_PUNCT_MASK | _PRINT_MASK, // '?' (ASCII 63)
|
||||
_PUNCT_MASK | _PRINT_MASK, // '@' (ASCII 64)
|
||||
// Upperchase letters (ASCII 65-90)
|
||||
_ALPHA_MASK | _PRINT_MASK, // 'A' (ASCII 65)
|
||||
_ALPHA_MASK | _PRINT_MASK, // 'B' (ASCII 66)
|
||||
_ALPHA_MASK | _PRINT_MASK, // 'C' (ASCII 67)
|
||||
_ALPHA_MASK | _PRINT_MASK, // 'D' (ASCII 68)
|
||||
_ALPHA_MASK | _PRINT_MASK, // 'E' (ASCII 69)
|
||||
_ALPHA_MASK | _PRINT_MASK, // 'F' (ASCII 70)
|
||||
_ALPHA_MASK | _PRINT_MASK, // 'G' (ASCII 71)
|
||||
_ALPHA_MASK | _PRINT_MASK, // 'H' (ASCII 72)
|
||||
_ALPHA_MASK | _PRINT_MASK, // 'I' (ASCII 73)
|
||||
_ALPHA_MASK | _PRINT_MASK, // 'J' (ASCII 74)
|
||||
_ALPHA_MASK | _PRINT_MASK, // 'K' (ASCII 75)
|
||||
_ALPHA_MASK | _PRINT_MASK, // 'L' (ASCII 76)
|
||||
_ALPHA_MASK | _PRINT_MASK, // 'M' (ASCII 77)
|
||||
_ALPHA_MASK | _PRINT_MASK, // 'N' (ASCII 78)
|
||||
_ALPHA_MASK | _PRINT_MASK, // 'O' (ASCII 79)
|
||||
_ALPHA_MASK | _PRINT_MASK, // 'P' (ASCII 80)
|
||||
_ALPHA_MASK | _PRINT_MASK, // 'Q' (ASCII 81)
|
||||
_ALPHA_MASK | _PRINT_MASK, // 'R' (ASCII 82)
|
||||
_ALPHA_MASK | _PRINT_MASK, // 'S' (ASCII 83)
|
||||
_ALPHA_MASK | _PRINT_MASK, // 'T' (ASCII 84)
|
||||
_ALPHA_MASK | _PRINT_MASK, // 'U' (ASCII 85)
|
||||
_ALPHA_MASK | _PRINT_MASK, // 'V' (ASCII 86)
|
||||
_ALPHA_MASK | _PRINT_MASK, // 'W' (ASCII 87)
|
||||
_ALPHA_MASK | _PRINT_MASK, // 'X' (ASCII 88)
|
||||
_ALPHA_MASK | _PRINT_MASK, // 'Y' (ASCII 89)
|
||||
_ALPHA_MASK | _PRINT_MASK, // 'Z' (ASCII 90)
|
||||
// Punctuation (ASCII 91-96)
|
||||
_PUNCT_MASK | _PRINT_MASK, // '[' (ASCII 91)
|
||||
_PUNCT_MASK | _PRINT_MASK, // '\' (ASCII 92)
|
||||
_PUNCT_MASK | _PRINT_MASK, // ']' (ASCII 93)
|
||||
_PUNCT_MASK | _PRINT_MASK, // '^' (ASCII 94)
|
||||
_PUNCT_MASK | _PRINT_MASK, // '_' (ASCII 95)
|
||||
_PUNCT_MASK | _PRINT_MASK, // '`' (ASCII 96)
|
||||
// Lowercase letters (ASCII 97-122)
|
||||
_ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'a' (ASCII 97)
|
||||
_ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'b' (ASCII 98)
|
||||
_ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'c' (ASCII 99)
|
||||
_ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'd' (ASCII 100)
|
||||
_ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'e' (ASCII 101)
|
||||
_ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'f' (ASCII 102)
|
||||
_ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'g' (ASCII 103)
|
||||
_ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'h' (ASCII 104)
|
||||
_ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'i' (ASCII 105)
|
||||
_ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'j' (ASCII 106)
|
||||
_ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'k' (ASCII 107)
|
||||
_ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'l' (ASCII 108)
|
||||
_ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'm' (ASCII 109)
|
||||
_ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'n' (ASCII 110)
|
||||
_ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'o' (ASCII 111)
|
||||
_ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'p' (ASCII 112)
|
||||
_ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'q' (ASCII 113)
|
||||
_ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'r' (ASCII 114)
|
||||
_ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 's' (ASCII 115)
|
||||
_ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 't' (ASCII 116)
|
||||
_ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'u' (ASCII 117)
|
||||
_ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'v' (ASCII 118)
|
||||
_ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'w' (ASCII 119)
|
||||
_ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'x' (ASCII 120)
|
||||
_ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'y' (ASCII 121)
|
||||
_ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'z' (ASCII 122)
|
||||
// Punctuation (ASCII 123-126
|
||||
_PUNCT_MASK | _PRINT_MASK, // '{' (ASCII 123)
|
||||
_PUNCT_MASK | _PRINT_MASK, // '|' (ASCII 124)
|
||||
_PUNCT_MASK | _PRINT_MASK, // '}' (ASCII 125)
|
||||
_PUNCT_MASK | _PRINT_MASK, // '~' (ASCII 126)
|
||||
// Control character (ASCII 127)
|
||||
_CNTRL_MASK // DEL (ASCII 127)
|
||||
};
|
||||
|
||||
+10
-11
@@ -1,5 +1,4 @@
|
||||
#include <kernel.h>
|
||||
#include <serial.h>
|
||||
#include <string.h>
|
||||
#include <system.h>
|
||||
#include <errno.h>
|
||||
@@ -99,16 +98,16 @@ void isr_handle_interrupt(size_t rsp) {
|
||||
struct isr_int_frame* iframe = (void*)rsp;
|
||||
|
||||
if (iframe->interrupt < 32) {
|
||||
debugf("[kernel] Register Dump:\n");
|
||||
debugf("\tRAX: %016lu RBX: %016lu RCX: %016lx\n", iframe->rax, iframe->rbx, iframe->rcx);
|
||||
debugf("\tRDX: %016lu RSI: %016lu RDI: %016lx\n", iframe->rdx, iframe->rsi, iframe->rdi);
|
||||
debugf("\tR08: %016lu R09: %016lu R10: %016lx\n", iframe->r8, iframe->r9, iframe->r10);
|
||||
debugf("\tR11: %016lu R12: %016lu R13: %016lx\n", iframe->r11, iframe->r12, iframe->r13);
|
||||
debugf("\tR14: %016lu R15: %016lu DS/ES: %016lx\n", iframe->r14, iframe->r15, iframe->ds);
|
||||
debugf("\tRBP: %016lu RSP: %016lu SS: %016lx\n", iframe->rbp, iframe->user_rsp, iframe->user_ss);
|
||||
debugf("\tRIP: %016lu RFLAGS: %016lx CS: %016lx\n", iframe->rip, iframe->rflags, iframe->cs);
|
||||
pr_emerg("Register Dump:\n");
|
||||
pr_emerg("\tRAX: %016lu RBX: %016lu RCX: %016lx\n", iframe->rax, iframe->rbx, iframe->rcx);
|
||||
pr_emerg("\tRDX: %016lu RSI: %016lu RDI: %016lx\n", iframe->rdx, iframe->rsi, iframe->rdi);
|
||||
pr_emerg("\tR08: %016lu R09: %016lu R10: %016lx\n", iframe->r8, iframe->r9, iframe->r10);
|
||||
pr_emerg("\tR11: %016lu R12: %016lu R13: %016lx\n", iframe->r11, iframe->r12, iframe->r13);
|
||||
pr_emerg("\tR14: %016lu R15: %016lu DS/ES: %016lx\n", iframe->r14, iframe->r15, iframe->ds);
|
||||
pr_emerg("\tRBP: %016lu RSP: %016lu SS: %016lx\n", iframe->rbp, iframe->user_rsp, iframe->user_ss);
|
||||
pr_emerg("\tRIP: %016lu RFLAGS: %016lx CS: %016lx\n", iframe->rip, iframe->rflags, iframe->cs);
|
||||
|
||||
if (iframe->error) debugf("[kernel] Error code: 0x%lx\n", iframe->error);
|
||||
if (iframe->error) pr_emerg("Error code: 0x%lx\n", iframe->error);
|
||||
panic(exceptions[iframe->interrupt]);
|
||||
} else if (iframe->interrupt >= 32 && iframe->interrupt < 48) {
|
||||
// ISRs 32-47 - Hardware interrupts
|
||||
@@ -117,7 +116,7 @@ void isr_handle_interrupt(size_t rsp) {
|
||||
if (irq_handlers[irq]) irq_handlers[irq](iframe);
|
||||
} else if (iframe->interrupt == 128) {
|
||||
// ISR 128 - System call
|
||||
debugf("SYSCALL!\n");
|
||||
pr_notice("SYSCALL!\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
#include <bootloader.h>
|
||||
#include <kernel.h>
|
||||
#include <paging.h>
|
||||
#include <serial.h>
|
||||
#include <splash.h>
|
||||
#include <system.h>
|
||||
#include <gdt.h>
|
||||
#include <pmm.h>
|
||||
#include <isr.h>
|
||||
|
||||
#include <kernel.h>
|
||||
#include <pmm.h>
|
||||
|
||||
__noreturn
|
||||
void _start(void) {
|
||||
@@ -24,7 +23,7 @@ void _start(void) {
|
||||
uint32_t eax = 0;
|
||||
char s[12];
|
||||
cpuid(&eax, (void*)&s[0], (void*)&s[8], (void*)&s[4]);
|
||||
debugf("[kernel] CPUID_GETVENDORID: %s\n", s);
|
||||
pr_info("[kernel] CPUID_GETVENDORID: %s\n", s);
|
||||
|
||||
// System init
|
||||
if (gdt_init() < 0) panic("Failed to initalize GDT.");
|
||||
@@ -34,6 +33,8 @@ void _start(void) {
|
||||
if (pmm_init() < 0) panic("Failed to initalize Physical Memory Manager.");
|
||||
if (pag_init() < 0) panic("Failed to initalize Paging.");
|
||||
|
||||
panic("Yeah..");
|
||||
|
||||
// Patiently wait for things to do :)
|
||||
while (1);
|
||||
}
|
||||
+3
-3
@@ -20,7 +20,7 @@ int pag_init(void) {
|
||||
pag_kernel_pml4,
|
||||
(void*)bootloader.kernel_virt_base,
|
||||
(void*)bootloader.kernel_phys_base,
|
||||
dceil(bootloader.executable->size, PAGE_SIZE),
|
||||
ALIGN(bootloader.executable->size, PAGE_SIZE),
|
||||
PTE_FLAG_WRITE | PTE_FLAG_PRESENT
|
||||
);
|
||||
if (ret != SUCCESS) return ret;
|
||||
@@ -40,7 +40,7 @@ int pag_init(void) {
|
||||
case LIMINE_MEMMAP_FRAMEBUFFER: flags = PTE_FLAG_WRITE | PTE_FLAG_PWT; break;
|
||||
case LIMINE_MEMMAP_RESERVED_MAPPED: flags = 0; break;
|
||||
default:
|
||||
debugf(
|
||||
pr_warning(
|
||||
"[pag] %p - %p: Unknown memmap type %d. Will remain unmapped.\n",
|
||||
entry->base, entry->base + entry->length, entry->type
|
||||
);
|
||||
@@ -50,7 +50,7 @@ int pag_init(void) {
|
||||
ret = pag_map_region(
|
||||
pag_kernel_pml4,
|
||||
(void*)(entry->base + bootloader.hhdm_offset), (void*)entry->base,
|
||||
dceil(entry->length, PAGE_SIZE),
|
||||
ALIGN(entry->length, PAGE_SIZE),
|
||||
flags | PTE_FLAG_PRESENT
|
||||
);
|
||||
if (ret != SUCCESS) return ret;
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
#include <vsnprintf.h>
|
||||
#include <kernel.h>
|
||||
#include <stdarg.h>
|
||||
#include <system.h>
|
||||
|
||||
static int crashing = 0;
|
||||
|
||||
void panic(const char *fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vpanic(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void vpanic(const char *fmt, va_list ap) {
|
||||
static char buf[PANIC_MSG_BUFSZ];
|
||||
size_t len;
|
||||
|
||||
cli();
|
||||
|
||||
if (crashing) { for (;;) __asm__ volatile ("hlt"); }
|
||||
crashing = true;
|
||||
|
||||
len = vsnprintf(buf, sizeof(buf), fmt, ap);
|
||||
if (len && buf[len - 1] == '\n') buf[len - 1] = '\0';
|
||||
|
||||
pr_emerg("--- [ Kernel panic: %s ] ---\n", buf);
|
||||
//pr_emerg("--- [ End kernel panic: %s ] ---\n", buf);
|
||||
|
||||
// We can add some kind of LED blink or smth later :)
|
||||
for (;;) __asm__ volatile ("hlt");
|
||||
}
|
||||
|
||||
+4
-5
@@ -2,7 +2,6 @@
|
||||
#include <kernel.h>
|
||||
#include <limine.h>
|
||||
#include <paging.h>
|
||||
#include <serial.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <pmm.h>
|
||||
@@ -11,11 +10,11 @@ uint64_t* pmm_head = NULL;
|
||||
size_t pmm_total_mem = 0;
|
||||
|
||||
int pmm_init(void) {
|
||||
debugf("[pmm] Physical memory map:\n"); // We're gonna use the loop to also print the memmap
|
||||
pr_info("[pmm] Physical memory map:\n"); // We're gonna use the loop to also print the memmap
|
||||
for (size_t i = 0; i < bootloader.mm_entry_count; i++) {
|
||||
struct limine_memmap_entry* entry = bootloader.mm_entries[i];
|
||||
|
||||
debugf(
|
||||
pr_info(
|
||||
"\t%p - %p (%d bytes), type %d\n",
|
||||
entry->base, entry->base + entry->length, entry->length, entry->type
|
||||
);
|
||||
@@ -25,7 +24,7 @@ int pmm_init(void) {
|
||||
// Limine spec says that it'll be aligned, but just as a sanity check
|
||||
if (entry->base % PAGE_SIZE != 0) {
|
||||
size_t diff = PAGE_SIZE - (entry->base % PAGE_SIZE);
|
||||
debugf("\t Not 4 kiB aligned, shifting %p -> %p (%d bytes).\n", entry->base, entry->base + diff, diff);
|
||||
pr_info("\t Not 4 kiB aligned, shifting %p -> %p (%d bytes).\n", entry->base, entry->base + diff, diff);
|
||||
entry->base += diff;
|
||||
entry->length -= diff;
|
||||
}
|
||||
@@ -38,7 +37,7 @@ int pmm_init(void) {
|
||||
}
|
||||
}
|
||||
|
||||
debugf("[pmm] %d bytes of available memory.\n", pmm_total_mem);
|
||||
pr_info("[pmm] %d bytes of available memory.\n", pmm_total_mem);
|
||||
if (pmm_total_mem == 0) return -ENOMEM;
|
||||
|
||||
return SUCCESS;
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
#include <kernel.h>
|
||||
#include <serial.h>
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
|
||||
uint8_t console_loglevel = CONSOLE_LOGLEVEL;
|
||||
|
||||
int printk(const char *fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
int ret = vprintk(fmt, ap);
|
||||
va_end(ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int vprintk(const char* fmt, va_list ap) {
|
||||
int loglevel = LOGLEVEL_DEFAULT;
|
||||
if (*fmt == KERN_SOH_ASCII) {
|
||||
fmt++;
|
||||
if (isdigit(*fmt)) loglevel = *fmt++ - '0';
|
||||
}
|
||||
|
||||
if (loglevel > console_loglevel) return 0;
|
||||
|
||||
// TODO: debugf("[%4d.%6d] ", seconds, milliseconds);
|
||||
return vdebugf(fmt, ap);
|
||||
}
|
||||
|
||||
+5
-5
@@ -43,16 +43,16 @@ char serial_recv(int dev) {
|
||||
return inb(dev);
|
||||
}
|
||||
|
||||
void serial_write(int dev, char* buf, size_t len) {
|
||||
void serial_write(int dev, const char* buf, size_t len) {
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
if (buf[i] == '\n') serial_send(dev, '\r');
|
||||
serial_send(dev, buf[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void serial_puts(int dev, char* s) {
|
||||
void serial_puts(int dev, const char* s) {
|
||||
size_t len = 0;
|
||||
char* p = s;
|
||||
const char* p = s;
|
||||
while (*p++ != '\0') len++;
|
||||
serial_write(dev, s, len);
|
||||
}
|
||||
@@ -61,7 +61,7 @@ void serial_cls(int dev) {
|
||||
serial_write(dev, "\x1b[H\x1b[J", 6);
|
||||
}
|
||||
|
||||
int debugf(char* fmt, ...) {
|
||||
int debugf(const char* fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
int ret = vdebugf(fmt, args);
|
||||
@@ -69,7 +69,7 @@ int debugf(char* fmt, ...) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
int vdebugf(char* fmt, va_list args) {
|
||||
int vdebugf(const char* fmt, va_list args) {
|
||||
char buf[DF_BUF_LEN];
|
||||
int len = vsnprintf(buf, DF_BUF_LEN, fmt, args);
|
||||
serial_write(COM1, buf, len);
|
||||
|
||||
@@ -109,7 +109,7 @@ static void fmt_float(char* buf, size_t n, size_t* idx, double v, int prec, int
|
||||
if (left) { while (pad_len--) _putc(buf, n, idx, pad); }
|
||||
}
|
||||
|
||||
int vsnprintf(char* buf, size_t n, char* fmt, va_list ap) {
|
||||
int vsnprintf(char* buf, size_t n, const char* fmt, va_list ap) {
|
||||
size_t idx = 0;
|
||||
|
||||
for (; *fmt != '\0'; fmt++) {
|
||||
@@ -195,7 +195,7 @@ int vsnprintf(char* buf, size_t n, char* fmt, va_list ap) {
|
||||
return (int)idx;
|
||||
}
|
||||
|
||||
int snprintf(char *buf, size_t n, char *fmt, ...) {
|
||||
int snprintf(char *buf, size_t n, const char *fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
int ret = vsnprintf(buf, n, fmt, ap);
|
||||
|
||||
Reference in New Issue
Block a user