fix(meowpanel): 文件列表排序——目录优先+名称不区分大小写(原 readdir 原始顺序混杂);条目上限 1024 防巨目录爆内存;设备实测生效

This commit is contained in:
MeowOS committed 2026-08-31 04:55:02 +08:00
1 parent f7e45f472e
commit c8ffdfbad9
2 files changed
+26 -8

No files matched your search

Binary file not shown.
+26 -8
View File
@@ -973,6 +973,16 @@ static void fmt_json_item(sbuf_t *s, const char *name, int isdir, long long size
isdir ? "dir" : "file", size, mtime);
}
struct fent { char name[256]; int isdir; long long size, mtime; };
/* 目录优先 + 名称不区分大小写(再按大小写敏感定序保证稳定) */
static int fent_cmp(const void *a, const void *b)
{
const struct fent *fa = a, *fb = b;
if (fa->isdir != fb->isdir) return fb->isdir - fa->isdir;
int c = strcasecmp(fa->name, fb->name);
return c ? c : strcmp(fa->name, fb->name);
}
static int files_list(int sock, const char *relpath)
{
char abs[1024], rel[1024];
@@ -999,7 +1009,10 @@ static int files_list(int sock, const char *relpath)
sA(&s, ",\"allowed\":[");
for (int i = 0; i < ALLOWED_COUNT; i++) { if (i) sA(&s, ","); sA_str(&s, g_allowed_dirs[i]); }
sA(&s, "],\"items\":[");
int first = 1;
/* M2.78:排序后输出(原 readdir 原始顺序混杂难用)——目录优先,同组按名称
* 不区分大小写排序;条目上限 1024(与 files App 一致,防巨目录爆内存)。 */
int cap = 1024, n = 0;
struct fent *ents = malloc((size_t)cap * sizeof *ents);
struct dirent *e;
while ((e = readdir(d))) {
if (!strcmp(e->d_name, ".") || !strcmp(e->d_name, "..")) continue;
@@ -1007,15 +1020,20 @@ static int files_list(int sock, const char *relpath)
snprintf(full, sizeof full, "%s/%s", abs, e->d_name);
struct stat fs;
if (stat(full, &fs) < 0) continue;
int isdir = S_ISDIR(fs.st_mode);
long long size = (long long)fs.st_size;
long long mtime = (long long)fs.st_mtime;
if (isdir) size = 0;
if (!first) sA(&s, ",");
first = 0;
fmt_json_item(&s, e->d_name, isdir, size, mtime);
if (n >= cap) break;
struct fent *en = &ents[n++];
snprintf(en->name, sizeof en->name, "%s", e->d_name);
en->isdir = S_ISDIR(fs.st_mode);
en->size = en->isdir ? 0 : (long long)fs.st_size;
en->mtime = (long long)fs.st_mtime;
}
closedir(d);
qsort(ents, (size_t)n, sizeof *ents, fent_cmp);
for (int i = 0; i < n; i++) {
if (i) sA(&s, ",");
fmt_json_item(&s, ents[i].name, ents[i].isdir, ents[i].size, ents[i].mtime);
}
free(ents);
sA(&s, "]}");
return send_json(sock, 200, s.b ? s.b : "");
}