mergerfs/vendored/libfuse/lib/xalloc.hpp
Antonio S. Musumeci 4516685ca7 libfuse: harden fuse.cpp against NULL nodes; use lock guards; check allocations
Collapse get_node/get_node_nocheck into a single function that
returns NULL when the node is absent rather than abort()ing.
Callers that previously assumed non-NULL now check the return value
and either reply ESTALE/ENOMEM or fall through gracefully; a few
places where the node is load-bearing (e.g. unhash during remove)
use fatal::abort with a descriptive message.

Switch mutex_lock / mutex_unlock pairs to mutex_lockguard so early
returns on error paths no longer leak the lock, and add NULL-safety
around fuse_dh in readdir/readdir_plus, fuse_dirents_init error
returns, the getattr path when both name and fh are empty, and the
msgbuf allocation in fuse_lib_read.

Pull the new xstrdup/xmalloc wrappers from xalloc.hpp for the root
node name so the common-case OOM path terminates with a diagnostic
instead of a silent corrupted node.

Also guard fuse_session_destroy against a NULL session - called
from error-recovery paths.
2026-04-18 13:47:23 -05:00

60 lines
1.1 KiB
C++

#pragma once
#include <stdio.h>
#include <stdlib.h>
#define xstrdup(S) xstrdup_impl((S),__FILE__,__LINE__)
#define xmalloc(S) xmalloc_impl((S),__FILE__,__LINE__)
static
inline
char*
xstrdup_impl(const char *s_,
const char *file_,
const unsigned line_)
{
char *p;
if(s_ == NULL)
{
fprintf(stderr,
"mergerfs: xstrdup called with NULL - file: %s; line: %u\n",
file_,
line_);
exit(EXIT_FAILURE);
}
p = strdup(s_);
if(p == NULL)
{
fprintf(stderr,
"mergerfs: strdup failed - file: %s; line: %u\n",
file_,
line_);
exit(EXIT_FAILURE);
}
return p;
}
static
inline
void*
xmalloc_impl(const size_t size_,
const char *file_,
const unsigned line_)
{
void *p;
p = malloc(size_);
if(p == NULL)
{
fprintf(stderr,
"mergerfs: malloc failed - file: %s; line: %u\n",
file_,
line_);
exit(EXIT_FAILURE);
}
return p;
}