mirror of
https://github.com/Leonmmcoset/cleonos.git
synced 2026-04-21 10:40:00 +00:00
wav支持2
This commit is contained in:
@@ -3,10 +3,8 @@
|
||||
|
||||
static int ush_cmd_cat(const ush_state *sh, const char *arg) {
|
||||
char path[USH_PATH_MAX];
|
||||
char buf[USH_CAT_MAX + 1ULL];
|
||||
u64 size;
|
||||
u64 req;
|
||||
u64 got;
|
||||
char buf[1024];
|
||||
u64 fd;
|
||||
|
||||
if (arg == (const char *)0 || arg[0] == '\0') {
|
||||
if (ush_pipeline_stdin_text != (const char *)0 && ush_pipeline_stdin_len > 0ULL) {
|
||||
@@ -28,36 +26,38 @@ static int ush_cmd_cat(const ush_state *sh, const char *arg) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
size = cleonos_sys_fs_stat_size(path);
|
||||
|
||||
if (size == (u64)-1) {
|
||||
(void)puts("cat: failed to stat file");
|
||||
fd = cleonos_sys_fd_open(path, CLEONOS_O_RDONLY, 0ULL);
|
||||
if (fd == (u64)-1) {
|
||||
(void)puts("cat: open failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (size == 0ULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
req = (size < USH_CAT_MAX) ? size : USH_CAT_MAX;
|
||||
got = cleonos_sys_fs_read(path, buf, req);
|
||||
|
||||
if (got == 0ULL) {
|
||||
(void)puts("cat: read failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (got > USH_CAT_MAX) {
|
||||
got = USH_CAT_MAX;
|
||||
}
|
||||
|
||||
buf[got] = '\0';
|
||||
(void)puts(buf);
|
||||
|
||||
if (size > got) {
|
||||
(void)puts("[cat] output truncated");
|
||||
for (;;) {
|
||||
u64 got = cleonos_sys_fd_read(fd, buf, (u64)sizeof(buf));
|
||||
u64 written_total = 0ULL;
|
||||
|
||||
if (got == (u64)-1) {
|
||||
(void)cleonos_sys_fd_close(fd);
|
||||
(void)puts("cat: read failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (got == 0ULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
while (written_total < got) {
|
||||
u64 written = cleonos_sys_fd_write(1ULL, buf + written_total, got - written_total);
|
||||
if (written == (u64)-1 || written == 0ULL) {
|
||||
(void)cleonos_sys_fd_close(fd);
|
||||
(void)puts("cat: write failed");
|
||||
return 0;
|
||||
}
|
||||
written_total += written;
|
||||
}
|
||||
}
|
||||
|
||||
(void)cleonos_sys_fd_close(fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,45 +1,60 @@
|
||||
#include "cmd_runtime.h"
|
||||
static int ush_copy_file(const char *src_path, const char *dst_path) {
|
||||
static char copy_buf[USH_COPY_MAX];
|
||||
u64 src_type;
|
||||
u64 src_size;
|
||||
u64 got;
|
||||
static char copy_buf[4096];
|
||||
u64 src_fd;
|
||||
u64 dst_fd;
|
||||
|
||||
src_type = cleonos_sys_fs_stat_type(src_path);
|
||||
|
||||
if (src_type != 1ULL) {
|
||||
if (cleonos_sys_fs_stat_type(src_path) != 1ULL) {
|
||||
ush_writeln("cp: source file not found");
|
||||
return 0;
|
||||
}
|
||||
|
||||
src_size = cleonos_sys_fs_stat_size(src_path);
|
||||
|
||||
if (src_size == (u64)-1) {
|
||||
ush_writeln("cp: failed to stat source");
|
||||
src_fd = cleonos_sys_fd_open(src_path, CLEONOS_O_RDONLY, 0ULL);
|
||||
if (src_fd == (u64)-1) {
|
||||
ush_writeln("cp: failed to open source");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (src_size > (u64)USH_COPY_MAX) {
|
||||
ush_writeln("cp: source too large for user shell buffer");
|
||||
dst_fd = cleonos_sys_fd_open(dst_path, CLEONOS_O_WRONLY | CLEONOS_O_CREAT | CLEONOS_O_TRUNC, 0ULL);
|
||||
if (dst_fd == (u64)-1) {
|
||||
(void)cleonos_sys_fd_close(src_fd);
|
||||
ush_writeln("cp: failed to open destination");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (src_size == 0ULL) {
|
||||
got = 0ULL;
|
||||
} else {
|
||||
got = cleonos_sys_fs_read(src_path, copy_buf, src_size);
|
||||
for (;;) {
|
||||
u64 got = cleonos_sys_fd_read(src_fd, copy_buf, (u64)sizeof(copy_buf));
|
||||
|
||||
if (got == 0ULL || got != src_size) {
|
||||
ush_writeln("cp: failed to read source");
|
||||
if (got == (u64)-1) {
|
||||
(void)cleonos_sys_fd_close(dst_fd);
|
||||
(void)cleonos_sys_fd_close(src_fd);
|
||||
ush_writeln("cp: read failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (got == 0ULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
{
|
||||
u64 written_total = 0ULL;
|
||||
while (written_total < got) {
|
||||
u64 written = cleonos_sys_fd_write(dst_fd,
|
||||
copy_buf + written_total,
|
||||
got - written_total);
|
||||
if (written == (u64)-1 || written == 0ULL) {
|
||||
(void)cleonos_sys_fd_close(dst_fd);
|
||||
(void)cleonos_sys_fd_close(src_fd);
|
||||
ush_writeln("cp: write failed");
|
||||
return 0;
|
||||
}
|
||||
written_total += written;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cleonos_sys_fs_write(dst_path, copy_buf, got) == 0ULL) {
|
||||
ush_writeln("cp: failed to write destination");
|
||||
return 0;
|
||||
}
|
||||
|
||||
(void)cleonos_sys_fd_close(dst_fd);
|
||||
(void)cleonos_sys_fd_close(src_fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "cmd_runtime.h"
|
||||
|
||||
#define USH_WAVPLAY_FILE_MAX 65536ULL
|
||||
#define USH_WAVPLAY_DEFAULT_STEPS 256ULL
|
||||
#define USH_WAVPLAY_MAX_STEPS 4096ULL
|
||||
#define USH_WAVPLAY_DEFAULT_TICKS 1ULL
|
||||
@@ -8,7 +7,6 @@
|
||||
#define USH_WAVPLAY_RUN_TICK_MAX 512ULL
|
||||
|
||||
typedef struct ush_wav_info {
|
||||
const unsigned char *data;
|
||||
u64 data_size;
|
||||
u64 frame_count;
|
||||
u64 sample_rate;
|
||||
@@ -17,8 +15,6 @@ typedef struct ush_wav_info {
|
||||
u64 block_align;
|
||||
} ush_wav_info;
|
||||
|
||||
static unsigned char ush_wavplay_file_buf[USH_WAVPLAY_FILE_MAX + 1ULL];
|
||||
|
||||
static unsigned int ush_wav_le16(const unsigned char *ptr) {
|
||||
return (unsigned int)ptr[0] | ((unsigned int)ptr[1] << 8U);
|
||||
}
|
||||
@@ -43,6 +39,50 @@ static int ush_wav_tag_eq(const unsigned char *tag, const char *lit4) {
|
||||
: 0;
|
||||
}
|
||||
|
||||
static int ush_wav_read_exact(u64 fd, unsigned char *out, u64 size) {
|
||||
u64 done = 0ULL;
|
||||
|
||||
if (out == (unsigned char *)0 || size == 0ULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (done < size) {
|
||||
u64 got = cleonos_sys_fd_read(fd, out + done, size - done);
|
||||
|
||||
if (got == (u64)-1 || got == 0ULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
done += got;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ush_wav_skip_bytes(u64 fd, u64 size) {
|
||||
unsigned char scratch[256];
|
||||
u64 remaining = size;
|
||||
|
||||
while (remaining > 0ULL) {
|
||||
u64 req = remaining;
|
||||
u64 got;
|
||||
|
||||
if (req > (u64)sizeof(scratch)) {
|
||||
req = (u64)sizeof(scratch);
|
||||
}
|
||||
|
||||
got = cleonos_sys_fd_read(fd, scratch, req);
|
||||
|
||||
if (got == (u64)-1 || got == 0ULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
remaining -= got;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void ush_wavplay_write_u64_dec(u64 value) {
|
||||
char rev[32];
|
||||
u64 len = 0ULL;
|
||||
@@ -84,70 +124,79 @@ static void ush_wavplay_print_meta(const char *path, const ush_wav_info *info, u
|
||||
ush_write_char('\n');
|
||||
}
|
||||
|
||||
static int ush_wav_parse(const unsigned char *buffer, u64 size, ush_wav_info *out_info) {
|
||||
u64 offset = 12ULL;
|
||||
static int ush_wav_parse_stream(u64 fd, ush_wav_info *out_info) {
|
||||
unsigned char riff_header[12];
|
||||
unsigned char chunk_header[8];
|
||||
unsigned char fmt_min[16];
|
||||
int found_fmt = 0;
|
||||
int found_data = 0;
|
||||
u64 sample_rate = 0ULL;
|
||||
u64 channels = 0ULL;
|
||||
u64 bits = 0ULL;
|
||||
u64 block_align = 0ULL;
|
||||
const unsigned char *data = (const unsigned char *)0;
|
||||
u64 data_size = 0ULL;
|
||||
|
||||
if (buffer == (const unsigned char *)0 || out_info == (ush_wav_info *)0) {
|
||||
if (out_info == (ush_wav_info *)0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (size < 12ULL) {
|
||||
if (ush_wav_read_exact(fd, riff_header, (u64)sizeof(riff_header)) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ush_wav_tag_eq(&buffer[0], "RIFF") == 0 || ush_wav_tag_eq(&buffer[8], "WAVE") == 0) {
|
||||
if (ush_wav_tag_eq(&riff_header[0], "RIFF") == 0 || ush_wav_tag_eq(&riff_header[8], "WAVE") == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (offset + 8ULL <= size) {
|
||||
const unsigned char *chunk_tag = &buffer[offset];
|
||||
u64 chunk_size = (u64)ush_wav_le32(&buffer[offset + 4ULL]);
|
||||
u64 chunk_data = offset + 8ULL;
|
||||
u64 next_offset;
|
||||
while (found_data == 0) {
|
||||
const unsigned char *chunk_tag;
|
||||
u64 chunk_size;
|
||||
|
||||
if (chunk_data > size || chunk_size > (size - chunk_data)) {
|
||||
if (ush_wav_read_exact(fd, chunk_header, (u64)sizeof(chunk_header)) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
chunk_tag = &chunk_header[0];
|
||||
chunk_size = (u64)ush_wav_le32(&chunk_header[4]);
|
||||
|
||||
if (ush_wav_tag_eq(chunk_tag, "fmt ") != 0) {
|
||||
if (chunk_size < 16ULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ush_wav_le16(&buffer[chunk_data + 0ULL]) != 1U) {
|
||||
if (ush_wav_read_exact(fd, fmt_min, (u64)sizeof(fmt_min)) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
channels = (u64)ush_wav_le16(&buffer[chunk_data + 2ULL]);
|
||||
sample_rate = (u64)ush_wav_le32(&buffer[chunk_data + 4ULL]);
|
||||
block_align = (u64)ush_wav_le16(&buffer[chunk_data + 12ULL]);
|
||||
bits = (u64)ush_wav_le16(&buffer[chunk_data + 14ULL]);
|
||||
if (ush_wav_le16(&fmt_min[0]) != 1U) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
channels = (u64)ush_wav_le16(&fmt_min[2]);
|
||||
sample_rate = (u64)ush_wav_le32(&fmt_min[4]);
|
||||
block_align = (u64)ush_wav_le16(&fmt_min[12]);
|
||||
bits = (u64)ush_wav_le16(&fmt_min[14]);
|
||||
found_fmt = 1;
|
||||
|
||||
if (chunk_size > 16ULL) {
|
||||
if (ush_wav_skip_bytes(fd, chunk_size - 16ULL) == 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} else if (ush_wav_tag_eq(chunk_tag, "data") != 0) {
|
||||
data = &buffer[chunk_data];
|
||||
data_size = chunk_size;
|
||||
found_data = 1;
|
||||
} else {
|
||||
if (ush_wav_skip_bytes(fd, chunk_size) == 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
next_offset = chunk_data + chunk_size;
|
||||
|
||||
if ((chunk_size & 1ULL) != 0ULL) {
|
||||
next_offset++;
|
||||
if ((chunk_size & 1ULL) != 0ULL && found_data == 0) {
|
||||
if (ush_wav_skip_bytes(fd, 1ULL) == 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (next_offset <= offset || next_offset > size) {
|
||||
break;
|
||||
}
|
||||
|
||||
offset = next_offset;
|
||||
}
|
||||
|
||||
if (found_fmt == 0 || found_data == 0) {
|
||||
@@ -166,7 +215,6 @@ static int ush_wav_parse(const unsigned char *buffer, u64 size, ush_wav_info *ou
|
||||
return 0;
|
||||
}
|
||||
|
||||
out_info->data = data;
|
||||
out_info->data_size = data_size;
|
||||
out_info->sample_rate = sample_rate;
|
||||
out_info->channels = channels;
|
||||
@@ -177,19 +225,11 @@ static int ush_wav_parse(const unsigned char *buffer, u64 size, ush_wav_info *ou
|
||||
return (out_info->frame_count > 0ULL) ? 1 : 0;
|
||||
}
|
||||
|
||||
static u64 ush_wav_sample_deviation(const ush_wav_info *info, u64 frame_index) {
|
||||
const unsigned char *frame;
|
||||
|
||||
if (info == (const ush_wav_info *)0 || info->data == (const unsigned char *)0 || info->frame_count == 0ULL) {
|
||||
static u64 ush_wav_frame_deviation(const ush_wav_info *info, const unsigned char *frame) {
|
||||
if (info == (const ush_wav_info *)0 || frame == (const unsigned char *)0) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
if (frame_index >= info->frame_count) {
|
||||
frame_index = info->frame_count - 1ULL;
|
||||
}
|
||||
|
||||
frame = &info->data[frame_index * info->block_align];
|
||||
|
||||
if (info->bits_per_sample == 8ULL) {
|
||||
unsigned int left = (unsigned int)frame[0];
|
||||
unsigned int dev_left = (left >= 128U) ? (left - 128U) : (128U - left);
|
||||
@@ -309,12 +349,13 @@ static int ush_wavplay_parse_args(const char *arg,
|
||||
static int ush_cmd_wavplay(const ush_state *sh, const char *arg) {
|
||||
char path_arg[USH_PATH_MAX];
|
||||
char abs_path[USH_PATH_MAX];
|
||||
unsigned char frame_buf[8];
|
||||
ush_wav_info info;
|
||||
u64 file_size;
|
||||
u64 got;
|
||||
u64 fd;
|
||||
u64 steps;
|
||||
u64 ticks_per_step;
|
||||
u64 stride;
|
||||
u64 current_frame = 0ULL;
|
||||
u64 i;
|
||||
u64 run_freq = 0ULL;
|
||||
u64 run_ticks = 0ULL;
|
||||
@@ -351,35 +392,30 @@ static int ush_cmd_wavplay(const ush_state *sh, const char *arg) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
file_size = cleonos_sys_fs_stat_size(abs_path);
|
||||
|
||||
if (file_size == (u64)-1 || file_size == 0ULL) {
|
||||
ush_writeln("wavplay: empty or unreadable file");
|
||||
fd = cleonos_sys_fd_open(abs_path, CLEONOS_O_RDONLY, 0ULL);
|
||||
if (fd == (u64)-1) {
|
||||
ush_writeln("wavplay: open failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (file_size > USH_WAVPLAY_FILE_MAX) {
|
||||
ush_writeln("wavplay: file too large (max 65536 bytes)");
|
||||
return 0;
|
||||
}
|
||||
|
||||
got = cleonos_sys_fs_read(abs_path, (char *)ush_wavplay_file_buf, file_size);
|
||||
|
||||
if (got != file_size) {
|
||||
ush_writeln("wavplay: read failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ush_wav_parse(ush_wavplay_file_buf, got, &info) == 0) {
|
||||
if (ush_wav_parse_stream(fd, &info) == 0) {
|
||||
(void)cleonos_sys_fd_close(fd);
|
||||
ush_writeln("wavplay: unsupported wav (need PCM 8/16-bit, mono/stereo)");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (info.block_align > (u64)sizeof(frame_buf)) {
|
||||
(void)cleonos_sys_fd_close(fd);
|
||||
ush_writeln("wavplay: unsupported block align");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (steps > info.frame_count) {
|
||||
steps = info.frame_count;
|
||||
}
|
||||
|
||||
if (steps == 0ULL) {
|
||||
(void)cleonos_sys_fd_close(fd);
|
||||
ush_writeln("wavplay: nothing to play");
|
||||
return 0;
|
||||
}
|
||||
@@ -403,12 +439,42 @@ static int ush_cmd_wavplay(const ush_state *sh, const char *arg) {
|
||||
u64 frame_index = i * stride;
|
||||
u64 deviation;
|
||||
u64 freq;
|
||||
u64 skip_frames;
|
||||
|
||||
if (frame_index >= info.frame_count) {
|
||||
frame_index = info.frame_count - 1ULL;
|
||||
}
|
||||
|
||||
deviation = ush_wav_sample_deviation(&info, frame_index);
|
||||
if (frame_index < current_frame) {
|
||||
(void)cleonos_sys_fd_close(fd);
|
||||
ush_writeln("wavplay: internal frame order error");
|
||||
return 0;
|
||||
}
|
||||
|
||||
skip_frames = frame_index - current_frame;
|
||||
if (skip_frames > 0ULL) {
|
||||
if (skip_frames > (0xFFFFFFFFFFFFFFFFULL / info.block_align)) {
|
||||
(void)cleonos_sys_fd_close(fd);
|
||||
ush_writeln("wavplay: frame skip overflow");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ush_wav_skip_bytes(fd, skip_frames * info.block_align) == 0) {
|
||||
(void)cleonos_sys_fd_close(fd);
|
||||
ush_writeln("wavplay: seek/read failed");
|
||||
return 0;
|
||||
}
|
||||
current_frame = frame_index;
|
||||
}
|
||||
|
||||
if (ush_wav_read_exact(fd, frame_buf, info.block_align) == 0) {
|
||||
(void)cleonos_sys_fd_close(fd);
|
||||
ush_writeln("wavplay: read failed");
|
||||
return 0;
|
||||
}
|
||||
current_frame++;
|
||||
|
||||
deviation = ush_wav_frame_deviation(&info, frame_buf);
|
||||
|
||||
if (deviation < 4ULL) {
|
||||
freq = 0ULL;
|
||||
@@ -428,6 +494,7 @@ static int ush_cmd_wavplay(const ush_state *sh, const char *arg) {
|
||||
}
|
||||
|
||||
if (cleonos_sys_audio_play_tone(run_freq, run_ticks) == 0ULL) {
|
||||
(void)cleonos_sys_fd_close(fd);
|
||||
ush_writeln("wavplay: playback failed");
|
||||
(void)cleonos_sys_audio_stop();
|
||||
return 0;
|
||||
@@ -439,12 +506,14 @@ static int ush_cmd_wavplay(const ush_state *sh, const char *arg) {
|
||||
|
||||
if (run_ticks > 0ULL) {
|
||||
if (cleonos_sys_audio_play_tone(run_freq, run_ticks) == 0ULL) {
|
||||
(void)cleonos_sys_fd_close(fd);
|
||||
ush_writeln("wavplay: playback failed");
|
||||
(void)cleonos_sys_audio_stop();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
(void)cleonos_sys_fd_close(fd);
|
||||
(void)cleonos_sys_audio_stop();
|
||||
ush_writeln("wavplay: done");
|
||||
return 1;
|
||||
@@ -492,4 +561,4 @@ int cleonos_app_main(void) {
|
||||
}
|
||||
|
||||
return (success != 0) ? 0 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#define CLKS_SYSCALL_PATH_MAX 192U
|
||||
#define CLKS_SYSCALL_NAME_MAX 96U
|
||||
#define CLKS_SYSCALL_TTY_MAX_LEN 2048U
|
||||
#define CLKS_SYSCALL_FS_IO_MAX_LEN 65536U
|
||||
#define CLKS_SYSCALL_FS_IO_CHUNK_LEN 65536U
|
||||
#define CLKS_SYSCALL_JOURNAL_MAX_LEN 256U
|
||||
#define CLKS_SYSCALL_ARG_LINE_MAX 256U
|
||||
#define CLKS_SYSCALL_ENV_LINE_MAX 512U
|
||||
@@ -1457,44 +1457,62 @@ static u64 clks_syscall_fs_mkdir(u64 arg0) {
|
||||
|
||||
static u64 clks_syscall_fs_write_common(u64 arg0, u64 arg1, u64 arg2, clks_bool append_mode) {
|
||||
char path[CLKS_SYSCALL_PATH_MAX];
|
||||
void *heap_copy = CLKS_NULL;
|
||||
const void *payload = CLKS_NULL;
|
||||
const u8 *src = (const u8 *)arg1;
|
||||
u64 remaining = arg2;
|
||||
clks_bool first_chunk = CLKS_TRUE;
|
||||
clks_bool ok;
|
||||
|
||||
if (clks_syscall_copy_user_string(arg0, path, sizeof(path)) == CLKS_FALSE) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
if (arg2 > CLKS_SYSCALL_FS_IO_MAX_LEN) {
|
||||
if (arg2 == 0ULL) {
|
||||
if (append_mode == CLKS_TRUE) {
|
||||
ok = clks_fs_append(path, CLKS_NULL, 0ULL);
|
||||
} else {
|
||||
ok = clks_fs_write_all(path, CLKS_NULL, 0ULL);
|
||||
}
|
||||
|
||||
return (ok == CLKS_TRUE) ? 1ULL : 0ULL;
|
||||
}
|
||||
|
||||
if (arg1 == 0ULL) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
if (arg2 > 0ULL) {
|
||||
if (arg1 == 0ULL) {
|
||||
return 0ULL;
|
||||
while (remaining > 0ULL) {
|
||||
u64 chunk_len = remaining;
|
||||
void *heap_copy;
|
||||
|
||||
if (chunk_len > CLKS_SYSCALL_FS_IO_CHUNK_LEN) {
|
||||
chunk_len = CLKS_SYSCALL_FS_IO_CHUNK_LEN;
|
||||
}
|
||||
|
||||
heap_copy = clks_kmalloc((usize)arg2);
|
||||
|
||||
heap_copy = clks_kmalloc((usize)chunk_len);
|
||||
if (heap_copy == CLKS_NULL) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
clks_memcpy(heap_copy, (const void *)arg1, (usize)arg2);
|
||||
payload = (const void *)heap_copy;
|
||||
}
|
||||
clks_memcpy(heap_copy, (const void *)src, (usize)chunk_len);
|
||||
|
||||
if (append_mode == CLKS_TRUE) {
|
||||
ok = clks_fs_append(path, payload, arg2);
|
||||
} else {
|
||||
ok = clks_fs_write_all(path, payload, arg2);
|
||||
}
|
||||
if (append_mode == CLKS_TRUE || first_chunk == CLKS_FALSE) {
|
||||
ok = clks_fs_append(path, heap_copy, chunk_len);
|
||||
} else {
|
||||
ok = clks_fs_write_all(path, heap_copy, chunk_len);
|
||||
}
|
||||
|
||||
if (heap_copy != CLKS_NULL) {
|
||||
clks_kfree(heap_copy);
|
||||
|
||||
if (ok == CLKS_FALSE) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
src += chunk_len;
|
||||
remaining -= chunk_len;
|
||||
first_chunk = CLKS_FALSE;
|
||||
}
|
||||
|
||||
return (ok == CLKS_TRUE) ? 1ULL : 0ULL;
|
||||
return 1ULL;
|
||||
}
|
||||
|
||||
static u64 clks_syscall_fs_write(u64 arg0, u64 arg1, u64 arg2) {
|
||||
|
||||
@@ -66,7 +66,7 @@ u64 cleonos_syscall(u64 id, u64 arg0, u64 arg1, u64 arg2);
|
||||
- 日志写入 `LOG_WRITE`:最大拷贝 `191` 字节。
|
||||
- TTY 文本写入 `TTY_WRITE`:最大拷贝 `512` 字节。
|
||||
- 文件读取 `FS_READ`:最多读取 `min(file_size, buffer_size)` 字节。
|
||||
- 文件写入 `FS_WRITE` / `FS_APPEND`:单次最大 `65536` 字节。
|
||||
- 文件写入 `FS_WRITE` / `FS_APPEND`:内核按 `65536` 字节分块搬运;这是实现分块大小,不是文件大小上限。
|
||||
- log journal 行读取缓冲:`256` 字节。
|
||||
- 路径缓冲上限:`192` 字节(包含 `\0`)。
|
||||
- 文件名输出上限:`96` 字节(与 `CLEONOS_FS_NAME_MAX` 对齐)。
|
||||
@@ -634,7 +634,7 @@ u64 cleonos_syscall(u64 id, u64 arg0, u64 arg1, u64 arg2);
|
||||
|
||||
- 传入的字符串/缓冲指针目前按“同地址空间可直接访问”模型处理,后续若引入严格用户态地址隔离,需要补充用户内存校验。
|
||||
- `FS_READ` 不保证文本终止符;读取文本请预留 1 字节并手动 `buf[n] = '\0'`。
|
||||
- `FS_WRITE`/`FS_APPEND` 仅允许 `/temp`,并有单次长度上限。
|
||||
- `FS_WRITE`/`FS_APPEND` 仅允许 `/temp`;大数据写入由内核自动分块处理。
|
||||
- `/proc` 由 syscall 层虚拟导出,不占用 RAMDISK 节点,也不能通过写入类 syscall 修改。
|
||||
|
||||
## 7. Wine 兼容说明
|
||||
|
||||
BIN
ramdisk/test.wav
BIN
ramdisk/test.wav
Binary file not shown.
Reference in New Issue
Block a user