1
0

proj: Implement shm_open, shm_unlink

This commit is contained in:
2025-03-01 15:27:22 +01:00
parent ae8dd9f8e6
commit aa5cb0ae9d
3 changed files with 204 additions and 56 deletions

View File

@@ -1,16 +1,18 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from typing import Optional, TypedDict
from typing import Optional, TypedDict, NotRequired
from socketserver import UnixStreamServer, StreamRequestHandler, ThreadingMixIn
import argparse
import os
import re
type Pointer[T] = tuple[int, T]
type Flags = tuple[int, list[str]]
type Pointer = int
type PointerTo[T] = tuple[Pointer, T]
type Flags = tuple[Pointer, list[str]]
StructTimeSpec = TypedDict('StructTimeSpec', {'tv_sec': int, 'tv_nsec': int})
StructSigAction = TypedDict('StructSigAction', {'sa_flags': Flags, 'sa_handler': NotRequired[Pointer], 'sa_sigaction': NotRequired[Pointer], 'sa_mask': list[str]})
class ThreadedUnixStreamServer(ThreadingMixIn, UnixStreamServer):
@@ -201,30 +203,30 @@ class Handler(StreamRequestHandler):
def before_malloc(self, size: int) -> str:
raise NotImplementedError()
def after_malloc(self, size: int,
ret_value: int, errno: str = None) -> None:
ret_value: Pointer, errno: str = None) -> None:
raise NotImplementedError()
def before_calloc(self, nmemb: int, size: int) -> str:
raise NotImplementedError()
def after_calloc(self, nmemb: int, size: int,
ret_value: int, errno: str = None) -> None:
ret_value: Pointer, errno: str = None) -> None:
raise NotImplementedError()
def before_realloc(self, ptr: int, size: int) -> str:
def before_realloc(self, ptr: Pointer, size: int) -> str:
raise NotImplementedError()
def after_realloc(self, ptr: int, size: int,
ret_value: int, errno: str = None) -> None:
def after_realloc(self, ptr: Pointer, size: int,
ret_value: Pointer, errno: str = None) -> None:
raise NotImplementedError()
def before_reallocarray(self, ptr: int, nmemb: int, size: int) -> str:
def before_reallocarray(self, ptr: Pointer, nmemb: int, size: int) -> str:
raise NotImplementedError()
def after_reallocarray(self, ptr: int, nmemb: int, size: int,
ret_value: int, errno: str = None) -> None:
def after_reallocarray(self, ptr: Pointer, nmemb: int, size: int,
ret_value: Pointer, errno: str = None) -> None:
raise NotImplementedError()
def before_free(self, ptr: int) -> str:
def before_free(self, ptr: Pointer) -> str:
raise NotImplementedError()
def after_free(self, ptr: int) -> None:
def after_free(self, ptr: Pointer) -> None:
raise NotImplementedError()
def before_getopt(self, argc: int, argv: Pointer[list[Pointer[bytes]]], optstring: Pointer[bytes]) -> str:
def before_getopt(self, argc: int, argv: PointerTo[list[PointerTo[bytes]]], optstring: PointerTo[bytes]) -> str:
raise NotImplementedError()
def after_getopt(self, argc: int, argv: Pointer[list[Pointer[bytes]]], optstring: Pointer[bytes],
def after_getopt(self, argc: int, argv: PointerTo[list[PointerTo[bytes]]], optstring: PointerTo[bytes],
ret_value: int) -> None:
raise NotImplementedError()
def before_close(self, fildes: int) -> str:
@@ -232,6 +234,11 @@ class Handler(StreamRequestHandler):
def after_close(self, fildes: int,
ret_value: int, errno: str = None) -> None:
raise NotImplementedError()
def before_sigaction(self, sig: int, act: PointerTo[StructSigAction], oact_ptr: Pointer) -> str:
raise NotImplementedError()
def after_sigaction(self, sig: int, act: PointerTo[StructSigAction], oact_ptr: Pointer,
ret_value: int, errno: str = None, oact: StructSigAction = None) -> None:
raise NotImplementedError()
def before_sem_init(self, sem: int, pshared: int, value: int) -> str:
raise NotImplementedError()
def after_sem_init(self, sem: int, pshared: int, value: int,
@@ -240,46 +247,56 @@ class Handler(StreamRequestHandler):
def before_sem_open(self, name: str, oflag: Flags, mode: Optional[int], value: Optional[int]) -> str:
raise NotImplementedError()
def after_sem_open(self, name: str, oflag: Flags, mode: Optional[int], value: Optional[int],
ret_value: Pointer, errno: str = None) -> None:
raise NotImplementedError()
def before_sem_post(self, sem: Pointer) -> str:
raise NotImplementedError()
def after_sem_post(self, sem: Pointer,
ret_value: int, errno: str = None) -> None:
raise NotImplementedError()
def before_sem_post(self, sem: int) -> str:
def before_sem_wait(self, sem: Pointer) -> str:
raise NotImplementedError()
def after_sem_post(self, sem: int,
def after_sem_wait(self, sem: Pointer,
ret_value: int, errno: str = None) -> None:
raise NotImplementedError()
def before_sem_wait(self, sem: int) -> str:
def before_sem_trywait(self, sem: Pointer) -> str:
raise NotImplementedError()
def after_sem_wait(self, sem: int,
def after_sem_trywait(self, sem: Pointer,
ret_value: int, errno: str = None) -> None:
raise NotImplementedError()
def before_sem_trywait(self, sem: int) -> str:
def before_sem_timedwait(self, sem: Pointer, abs_timeout: PointerTo[StructTimeSpec]) -> str:
raise NotImplementedError()
def after_sem_trywait(self, sem: int,
def after_sem_timedwait(self, sem: Pointer, abs_timeout: PointerTo[StructTimeSpec],
ret_value: int, errno: str = None) -> None:
raise NotImplementedError()
def before_sem_timedwait(self, sem: int, abs_timeout: Pointer[StructTimeSpec]) -> str:
def before_sem_getvalue(self, sem: Pointer, value_ptr: Pointer) -> str:
raise NotImplementedError()
def after_sem_timedwait(self, sem: int, abs_timeout: Pointer[StructTimeSpec],
ret_value: int, errno: str = None) -> None:
raise NotImplementedError()
def before_sem_getvalue(self, sem: int, value_ptr: int) -> str:
raise NotImplementedError()
def after_sem_getvalue(self, sem:int, value_ptr: int,
def after_sem_getvalue(self, sem: Pointer, value_ptr: Pointer,
ret_value: int, errno: str = None, value: int = None) -> None:
raise NotImplementedError()
def before_sem_close(self, sem: int) -> str:
def before_sem_close(self, sem: Pointer) -> str:
raise NotImplementedError()
def after_sem_close(self, sem: int,
def after_sem_close(self, sem: Pointer,
ret_value: int, errno: str = None) -> None:
raise NotImplementedError()
def before_sem_unlink(self, name: Pointer[bytes]) -> str:
def before_sem_unlink(self, name: PointerTo[bytes]) -> str:
raise NotImplementedError()
def after_sem_unlink(self, name: Pointer[bytes],
def after_sem_unlink(self, name: PointerTo[bytes],
ret_value: int, errno: str = None) -> None:
raise NotImplementedError()
def before_sem_destroy(self, sem: int) -> str:
def before_sem_destroy(self, sem: Pointer) -> str:
raise NotImplementedError()
def after_sem_destroy(self, sem: int,
def after_sem_destroy(self, sem: Pointer,
ret_value: int, errno: str = None) -> None:
raise NotImplementedError()
def before_shm_open(self, name: PointerTo[bytes], oflag: Flags, mode: int) -> str:
raise NotImplementedError()
def after_shm_open(self, name: PointerTo[bytes], oflag: Flags, mode: int,
ret_value: int, errno: str = None) -> None:
raise NotImplementedError()
def before_shm_unlink(self, name: PointerTo[bytes]) -> str:
raise NotImplementedError()
def after_shm_unlink(self, name: PointerTo[bytes],
ret_value: int, errno: str = None) -> None:
raise NotImplementedError()

View File

@@ -26,7 +26,8 @@ main: bin/main.o
main_intercept: bin/main.o src/intercept.c
$(CC) -o $@ $^ $(CFLAGS) -lc -Wl,--wrap=malloc,--wrap=free,--wrap=calloc,--wrap=realloc,--wrap=reallocarray,--wrap=getopt,--wrap=exit,--wrap=close,--wrap=sigaction,\
--wrap=sem_init,--wrap=sem_open,--wrap=sem_post,--wrap=sem_wait,--wrap=sem_trywait,--wrap=sem_timedwait,--wrap=sem_getvalue,--wrap=sem_close,--wrap=sem_unlink,--wrap=sem_destroy
--wrap=sem_init,--wrap=sem_open,--wrap=sem_post,--wrap=sem_wait,--wrap=sem_trywait,--wrap=sem_timedwait,--wrap=sem_getvalue,--wrap=sem_close,--wrap=sem_unlink,--wrap=sem_destroy,\
--wrap=shm_open,--wrap=shm_unlink
clean:
rm -rf main main_wrapped bin/* *.so *.ko *.o

View File

@@ -40,6 +40,8 @@ static int (*__real_sem_getvalue)(sem_t *restrict, int *restrict);
static int (*__real_sem_close)(sem_t *);
static int (*__real_sem_unlink)(const char *);
static int (*__real_sem_destroy)(sem_t *);
static int (*__real_shm_open)(const char *, int, mode_t);
static int (*__real_shm_unlink)(const char *);
#define load(name) \
if (((__real_ ## name) = dlsym(RTLD_NEXT, #name)) == NULL) { \
fprintf(stderr, "intercept: unable to load symbol '%s': %s", #name, strerror(errno)); \
@@ -66,9 +68,13 @@ extern int __real_sem_getvalue(sem_t *restrict, int *restrict);
extern int __real_sem_close(sem_t *);
extern int __real_sem_unlink(const char *);
extern int __real_sem_destroy(sem_t *);
extern int __real_shm_open(const char *, int, mode_t);
extern int __real_shm_unlink(const char *);
#define sym(name) __wrap_ ## name
#endif
#define ret_addr __builtin_return_address(0)
#define if_invalid(name) if (strcmp(buf, "ok") != 0) { fprintf(stderr, "intercept: " #name ": invalid command: '%s'\n", buf); }
#define if_modify_int(name, type_1, var_1) if (strncmp(buf, "modify ", 7) == 0) { \
@@ -199,6 +205,21 @@ extern int __real_sem_destroy(sem_t *);
msg("return %i; errno %s", -1, strerrorname_np(errno)); \
return -1; }
#define if_error_7_int_errno(name, err1, err2, err3, err4, err5, err6, err7) if (strncmp(buf, "fail ", 5) == 0) { \
if (strcmp(buf + 5, #err1) == 0) { errno = err1; \
} else if (strcmp(buf + 5, #err2) == 0) { errno = err2; \
} else if (strcmp(buf + 5, #err3) == 0) { errno = err3; \
} else if (strcmp(buf + 5, #err4) == 0) { errno = err4; \
} else if (strcmp(buf + 5, #err5) == 0) { errno = err5; \
} else if (strcmp(buf + 5, #err6) == 0) { errno = err6; \
} else if (strcmp(buf + 5, #err6) == 0) { errno = err7; \
} else { \
errno = 0; \
fprintf(stderr, "intercept: " #name ": invalid error code in fail command: '%s'\n", buf + 5); \
} \
msg("return %i; errno %s", -1, strerrorname_np(errno)); \
return -1; }
#define if_error_8_ptr_errno(name, err1, err2, err3, err4, err5, err6, err7, err8) if (strncmp(buf, "fail ", 5) == 0) { \
if (strcmp(buf + 5, #err1) == 0) { errno = err1; \
} else if (strcmp(buf + 5, #err2) == 0) { errno = err2; \
@@ -456,6 +477,8 @@ static void init(void) {
load(sem_close);
load(sem_unlink);
load(sem_destroy);
load(shm_open);
load(shm_unlink);
#endif
atexit(fin);
const char *val = getenv("INTERCEPT");
@@ -506,7 +529,7 @@ static void init(void) {
void *sym(malloc)(size_t size) {
init();
msg("malloc(%li): %p", size, __builtin_return_address(0));
msg("malloc(%li): %p", size, ret_addr);
if (mode >= 4) {
char buf[BUFFER_SIZE];
rcv(buf, sizeof(buf));
@@ -522,7 +545,7 @@ void *sym(malloc)(size_t size) {
void *sym(calloc)(size_t nmemb, size_t size) {
init();
msg("calloc(%li, %li): %p", nmemb, size, __builtin_return_address(0));
msg("calloc(%li, %li): %p", nmemb, size, ret_addr);
if (mode >= 4) {
char buf[BUFFER_SIZE];
rcv(buf, sizeof(buf));
@@ -538,7 +561,7 @@ void *sym(calloc)(size_t nmemb, size_t size) {
void *sym(realloc)(void *ptr, size_t size) {
init();
msg("realloc(%p, %li): %p", ptr, size, __builtin_return_address(0));
msg("realloc(%p, %li): %p", ptr, size, ret_addr);
if (mode >= 4) {
char buf[BUFFER_SIZE];
rcv(buf, sizeof(buf));
@@ -554,7 +577,7 @@ void *sym(realloc)(void *ptr, size_t size) {
void *sym(reallocarray)(void *ptr, size_t nmemb, size_t size) {
init();
msg("reallocarray(%p, %li): %p", ptr, size, __builtin_return_address(0));
msg("reallocarray(%p, %li): %p", ptr, size, ret_addr);
if (mode >= 4) {
char buf[BUFFER_SIZE];
rcv(buf, sizeof(buf));
@@ -570,7 +593,7 @@ void *sym(reallocarray)(void *ptr, size_t nmemb, size_t size) {
void sym(free)(void *ptr) {
init();
msg("free(%p): %p", ptr, __builtin_return_address(0));
msg("free(%p): %p", ptr, ret_addr);
if (mode >= 4) {
char buf[BUFFER_SIZE];
rcv(buf, sizeof(buf));
@@ -584,7 +607,7 @@ void sym(free)(void *ptr) {
int sym(getopt)(const int argc, char *const argv[], const char *shortopts) {
init();
msg("getopt(%i, %as, %es): %p", argc, argv, argc, shortopts, __builtin_return_address(0));
msg("getopt(%i, %as, %es): %p", argc, argv, argc, shortopts, ret_addr);
if (mode >= 4) {
char buf[BUFFER_SIZE];
rcv(buf, sizeof(buf));
@@ -602,7 +625,7 @@ int sym(getopt)(const int argc, char *const argv[], const char *shortopts) {
void sym(exit)(int status) {
init();
msg("exit(%i): %p", status, __builtin_return_address(0));
msg("exit(%i): %p", status, ret_addr);
if (mode >= 4) {
char buf[BUFFER_SIZE];
rcv(buf, sizeof(buf));
@@ -614,7 +637,7 @@ void sym(exit)(int status) {
int sym(close)(int fildes) {
init();
msg("close(%i): %p", fildes, __builtin_return_address(0));
msg("close(%i): %p", fildes, ret_addr);
if (mode >= 4) {
char buf[BUFFER_SIZE];
rcv(buf, sizeof(buf));
@@ -685,9 +708,9 @@ int sym(sigaction)(int sig, const struct sigaction *restrict act, struct sigacti
if (maskstr[0] != 0) strcat(maskstr, ",");
strcat(maskstr, getsigstr(i));
}
msg("sigaction(%i:%s, %p:{sa_flags: 0x%x:%s, %s: %p, sa_mask: [%s]}, %p): %p", sig, sigstr, act, act->sa_flags, flgstr, name, ptr, maskstr, oact, __builtin_return_address(0));
msg("sigaction(%i:%s, %p:{sa_flags: 0x%x:%s, %s: %p, sa_mask: [%s]}, %p): %p", sig, sigstr, act, act->sa_flags, flgstr, name, ptr, maskstr, oact, ret_addr);
} else {
msg("sigaction(%i:%s, %p:{}, %p): %p", sig, sigstr, act, oact, __builtin_return_address(0));
msg("sigaction(%i:%s, %p:{}, %p): %p", sig, sigstr, act, oact, ret_addr);
}
if (mode >= 4) {
char buf[BUFFER_SIZE];
@@ -730,7 +753,7 @@ int sym(sigaction)(int sig, const struct sigaction *restrict act, struct sigacti
int sym(sem_init)(sem_t *sem, int pshared, unsigned int value) {
init();
msg("sem_init(%p, %i, %u): %p", sem, pshared, value, __builtin_return_address(0));
msg("sem_init(%p, %i, %u): %p", sem, pshared, value, ret_addr);
if (mode >= 4) {
char buf[BUFFER_SIZE];
rcv(buf, sizeof(buf));
@@ -759,9 +782,9 @@ sem_t *sym(sem_open)(const char *name, int oflag, ...) {
mode_arg = va_arg(args, mode_t);
value = va_arg(args, unsigned int);
va_end(args);
msg("sem_open(%es, 0%o:%s, 0%03o, %u): %p", name, oflag, ostr, mode_arg, value, __builtin_return_address(0));
msg("sem_open(%es, 0%o:%s, 0%03o, %u): %p", name, oflag, ostr, mode_arg, value, ret_addr);
} else {
msg("sem_open(%es, 0%o:|%s): %p", name, oflag, ostr, __builtin_return_address(0));
msg("sem_open(%es, 0%o:|%s): %p", name, oflag, ostr, ret_addr);
}
char overwrite[BUFFER_SIZE];
@@ -831,7 +854,7 @@ sem_t *sym(sem_open)(const char *name, int oflag, ...) {
int sym(sem_post)(sem_t *sem) {
init();
msg("sem_post(%p): %p", sem, __builtin_return_address(0));
msg("sem_post(%p): %p", sem, ret_addr);
if (mode >= 4) {
char buf[BUFFER_SIZE];
rcv(buf, sizeof(buf));
@@ -847,7 +870,7 @@ int sym(sem_post)(sem_t *sem) {
int sym(sem_wait)(sem_t *sem) {
init();
msg("sem_wait(%p): %p", sem, __builtin_return_address(0));
msg("sem_wait(%p): %p", sem, ret_addr);
if (mode >= 4) {
char buf[BUFFER_SIZE];
rcv(buf, sizeof(buf));
@@ -863,7 +886,7 @@ int sym(sem_wait)(sem_t *sem) {
int sym(sem_trywait)(sem_t *sem) {
init();
msg("sem_trywait(%p): %p", sem, __builtin_return_address(0));
msg("sem_trywait(%p): %p", sem, ret_addr);
if (mode >= 4) {
char buf[BUFFER_SIZE];
rcv(buf, sizeof(buf));
@@ -879,7 +902,7 @@ int sym(sem_trywait)(sem_t *sem) {
int sym(sem_timedwait)(sem_t *restrict sem, const struct timespec *restrict abs_timeout) {
init();
msg("sem_timedwait(%p, %p:{tv_sec: %li, tv_nsec: %li}): %p", sem, abs_timeout, abs_timeout->tv_sec, abs_timeout->tv_nsec, __builtin_return_address(0));
msg("sem_timedwait(%p, %p:{tv_sec: %li, tv_nsec: %li}): %p", sem, abs_timeout, abs_timeout->tv_sec, abs_timeout->tv_nsec, ret_addr);
struct timespec overwrite;
if (mode >= 4) {
char buf[BUFFER_SIZE];
@@ -924,7 +947,7 @@ int sym(sem_timedwait)(sem_t *restrict sem, const struct timespec *restrict abs_
int sym(sem_getvalue)(sem_t *restrict sem, int *restrict value) {
init();
msg("sem_getvalue(%p, %p): %p", sem, value, __builtin_return_address(0));
msg("sem_getvalue(%p, %p): %p", sem, value, ret_addr);
if (mode >= 4) {
char buf[BUFFER_SIZE];
rcv(buf, sizeof(buf));
@@ -944,7 +967,7 @@ int sym(sem_getvalue)(sem_t *restrict sem, int *restrict value) {
int sym(sem_close)(sem_t *sem) {
init();
msg("sem_close(%p): %p", sem, __builtin_return_address(0));
msg("sem_close(%p): %p", sem, ret_addr);
if (mode >= 4) {
char buf[BUFFER_SIZE];
rcv(buf, sizeof(buf));
@@ -960,7 +983,7 @@ int sym(sem_close)(sem_t *sem) {
int sym(sem_unlink)(const char *name) {
init();
msg("sem_unlink(%es): %p", name, __builtin_return_address(0));
msg("sem_unlink(%es): %p", name, ret_addr);
char overwrite[BUFFER_SIZE];
if (mode >= 4) {
char buf[BUFFER_SIZE];
@@ -991,7 +1014,7 @@ int sym(sem_unlink)(const char *name) {
int sym(sem_destroy)(sem_t *sem) {
init();
msg("sem_destroy(%p): %p", sem, __builtin_return_address(0));
msg("sem_destroy(%p): %p", sem, ret_addr);
if (mode >= 4) {
char buf[BUFFER_SIZE];
rcv(buf, sizeof(buf));
@@ -1004,3 +1027,110 @@ int sym(sem_destroy)(sem_t *sem) {
msg("return %p; errno %s", ret, strerrorname_np(errno));
return ret;
}
int sym(shm_open)(const char *name, int oflag, mode_t mode_arg) {
init();
char ostr[64] = "|";
if (oflag & O_RDONLY) strcat(ostr, "O_RDONLY|");
if (oflag & O_RDWR) strcat(ostr, "O_RDWR|");
if (oflag & O_CREAT) strcat(ostr, "O_CREAT|");
if (oflag & O_EXCL) strcat(ostr, "O_EXCL|");
if (oflag & O_TRUNC) strcat(ostr, "O_TRUNC|");
if (oflag & ~(O_RDONLY | O_RDWR | O_CREAT | O_EXCL | O_TRUNC)) strcat(ostr, "?|");
msg("shm_open(%es, 0%o:%s, 0%o): %p", name, oflag, ostr, mode_arg, ret_addr);
char overwrite[BUFFER_SIZE];
if (mode >= 4) {
char buf[BUFFER_SIZE];
rcv(buf, sizeof(buf));
if (strncmp(buf, "modify ", 7) == 0) {
// modify <name>,<oflag>,<mode>
char *val_1 = NULL, *end_ptr_1 = NULL, *end_ptr_2 = NULL, *end_ptr_3 = NULL;
long val_2 = 0, val_3 = 0;
if (buf[7] == '"') {
// modify "<name>",...
val_1 = strtostr(buf + 7, &end_ptr_1, overwrite);
if (val_1 == NULL) end_ptr_1 = NULL;
} else {
// modify <name_ptr>,...
val_1 = (char *)strtol(buf + 7, &end_ptr_1, 0);
}
if (end_ptr_1 != NULL && end_ptr_1[0] != 0) {
if (end_ptr_1[1] == '|') {
val_2 = 0;
end_ptr_2 = end_ptr_1 + 1;
if (strncmp(end_ptr_2, "O_RDONLY|", 8) == 0) {
val_2 |= O_RDONLY;
end_ptr_2 += 9;
}
if (strncmp(end_ptr_2, "O_RDWR|", 8) == 0) {
val_2 |= O_RDWR;
end_ptr_2 += 7;
}
if (strncmp(end_ptr_2, "O_CREAT|", 8) == 0) {
val_2 |= O_CREAT;
end_ptr_2 += 8;
}
if (strncmp(end_ptr_2, "O_EXCL|", 7) == 0) {
val_2 |= O_EXCL;
end_ptr_2 += 7;
}
if (strncmp(end_ptr_2, "O_TRUNC|", 7) == 0) {
val_2 |= O_TRUNC;
end_ptr_2 += 8;
}
} else {
val_2 = strtol(end_ptr_1 + 1, &end_ptr_2, 0);
}
}
if (end_ptr_2 != NULL && end_ptr_2[0] != 0) val_3 = strtol(end_ptr_2 + 1, &end_ptr_3, 0);
if (end_ptr_1 != NULL && end_ptr_1[0] == ',' && end_ptr_1 != buf + 7 &&
end_ptr_2 != NULL && end_ptr_2[0] == ',' && end_ptr_2 != end_ptr_1 + 1 &&
end_ptr_3 != NULL && end_ptr_3[0] == 0 && end_ptr_3 != end_ptr_2 + 1)
{
name = val_1;
oflag = (int)val_2;
mode_arg = val_3;
} else {
fprintf(stderr, "intercept: shm_open: invalid args in modify command: '%s'\n", buf + 7); \
}
} else if_return_int_errno(shm_open)
else if_error_7_int_errno(shm_open, EACCES, EEXIST, EINVAL, EMFILE, ENAMETOOLONG, ENFILE, ENOENT)
else if_invalid(shm_open)
}
const int ret = __real_shm_open(name, oflag, mode);
msg("return %i; errno %s", ret, strerrorname_np(errno));
return ret;
}
int sym(shm_unlink)(const char *name) {
init();
msg("shm_unlink(%es): %p", name, ret_addr);
char overwrite[BUFFER_SIZE];
if (mode >= 4) {
char buf[BUFFER_SIZE];
rcv(buf, sizeof(buf));
if (strncmp(buf, "modify ", 7) == 0) {
char *end_ptr = NULL, *val = NULL;
if (buf[7] == '"') {
// modify "<name>"
val = strtostr(buf + 7, &end_ptr, overwrite);
if (val == NULL) end_ptr = NULL;
} else {
// modify <name_ptr>
val = (char *)strtol(buf + 7, &end_ptr, 0);
}
if (end_ptr != NULL && end_ptr[0] == 0 && end_ptr != buf + 7) {
name = val;
} else {
fprintf(stderr, "intercept: shm_unlink: invalid args in modify command: '%s'\n", buf + 7); \
}
} else if_return_int_errno(shm_unlink)
else if_error_3_int_errno(shm_unlink, EACCES, ENAMETOOLONG, ENOENT)
else if_invalid(shm_unlink)
}
const int ret = __real_shm_unlink(name);
msg("return %i; errno %s", ret, strerrorname_np(errno));
return ret;
}