fs_node_t* rnode = NULL;
fs_node_t* wnode = NULL;
- if (pipe_node_create(ps, 1, &rnode) < 0 || pipe_node_create(ps, 0, &wnode) < 0) {
- if (rnode) vfs_close(rnode);
- if (wnode) vfs_close(wnode);
- if (ps->buf) kfree(ps->buf);
+ if (pipe_node_create(ps, 1, &rnode) < 0) {
+ kfree(ps->buf);
kfree(ps);
return -ENOMEM;
}
+ if (pipe_node_create(ps, 0, &wnode) < 0) {
+ vfs_close(rnode);
+ return -ENOMEM;
+ }
struct file* rf = (struct file*)kmalloc(sizeof(*rf));
struct file* wf = (struct file*)kmalloc(sizeof(*wf));
static void path_normalize_inplace(char* s) {
if (!s) return;
- // Collapse duplicate slashes and remove trailing slash (except for root).
- char tmp[128];
- size_t w = 0;
- size_t r = 0;
if (s[0] == 0) {
strcpy(s, "/");
return;
}
- while (s[r] != 0 && w + 1 < sizeof(tmp)) {
- char c = s[r++];
- if (c == '/') {
- if (w == 0 || tmp[w - 1] != '/') {
- tmp[w++] = '/';
+ // Phase 1: split into components, resolve '.' and '..'
+ char tmp[128];
+ // Stack of component start offsets within tmp
+ size_t comp_start[32];
+ int depth = 0;
+ size_t w = 0;
+
+ const char* p = s;
+ int absolute = (*p == '/');
+ if (absolute) {
+ tmp[w++] = '/';
+ while (*p == '/') p++;
+ }
+
+ while (*p != 0) {
+ // Extract next component
+ const char* seg = p;
+ while (*p != 0 && *p != '/') p++;
+ size_t seg_len = (size_t)(p - seg);
+ while (*p == '/') p++;
+
+ if (seg_len == 1 && seg[0] == '.') {
+ continue; // skip '.'
+ }
+
+ if (seg_len == 2 && seg[0] == '.' && seg[1] == '.') {
+ // Go up one level
+ if (depth > 0) {
+ depth--;
+ w = comp_start[depth];
}
- } else {
- tmp[w++] = c;
+ continue;
+ }
+
+ // Record start of this component
+ if (depth < 32) {
+ comp_start[depth++] = w;
+ }
+
+ // Append separator if needed
+ if (w > 1 || (w == 1 && tmp[0] != '/')) {
+ if (w + 1 < sizeof(tmp)) tmp[w++] = '/';
+ }
+
+ // Append component
+ for (size_t i = 0; i < seg_len && w + 1 < sizeof(tmp); i++) {
+ tmp[w++] = seg[i];
}
}
- tmp[w] = 0;
- size_t l = strlen(tmp);
- while (l > 1 && tmp[l - 1] == '/') {
- tmp[l - 1] = 0;
- l--;
+ // Handle empty result
+ if (w == 0) {
+ tmp[w++] = '/';
}
+ // Remove trailing slash (except root)
+ while (w > 1 && tmp[w - 1] == '/') {
+ w--;
+ }
+
+ tmp[w] = 0;
strcpy(s, tmp);
}
// Only coalesce if physically adjacent.
heap_header_t* expected_next = (heap_header_t*)((uint8_t*)header + sizeof(heap_header_t) + header->size);
- if (next_block != expected_next) {
- spin_unlock_irqrestore(&heap_lock, flags);
- return;
- }
-
- header->size += sizeof(heap_header_t) + next_block->size;
- header->next = next_block->next;
-
- if (header->next) {
- header->next->prev = header;
- } else {
- tail = header; // If next was tail, now current is tail
+ if (next_block == expected_next) {
+ header->size += sizeof(heap_header_t) + next_block->size;
+ header->next = next_block->next;
+
+ if (header->next) {
+ header->next->prev = header;
+ } else {
+ tail = header;
+ }
}
}
// Only coalesce if physically adjacent.
heap_header_t* expected_hdr = (heap_header_t*)((uint8_t*)prev_block + sizeof(heap_header_t) + prev_block->size);
- if (expected_hdr != header) {
- spin_unlock_irqrestore(&heap_lock, flags);
- return;
- }
-
- prev_block->size += sizeof(heap_header_t) + header->size;
- prev_block->next = header->next;
-
- if (header->next) {
- header->next->prev = prev_block;
- } else {
- tail = prev_block;
+ if (expected_hdr == header) {
+ prev_block->size += sizeof(heap_header_t) + header->size;
+ prev_block->next = header->next;
+
+ if (header->next) {
+ header->next->prev = prev_block;
+ } else {
+ tail = prev_block;
+ }
}
- // No need to update 'header' anymore, prev_block is the merged one
}
spin_unlock_irqrestore(&heap_lock, flags);