MT#65481 add open/read/write mockups

Change-Id: Ibe6da6909bc6293b3e96a1822f8305ae7f25ff76
pull/2149/head
Richard Fuchs 4 weeks ago
parent bba144c577
commit a4746a9ac4

@ -25,6 +25,7 @@ typedef struct {
struct sockaddr_storage sockname,
peername;
unsigned int open:1,
mock:1,
bound:1,
connected:1,
pktinfo:1;
@ -53,6 +54,17 @@ static const struct sockaddr *addr_find(const struct sockaddr *addr, socklen_t *
static const char *p_prefix;
#define MAX_MOCK_FILES 16
static const char *mock_files[MAX_MOCK_FILES];
static const char *mock_peer;
enum mock_msg {
MOCK_OPEN = 1,
MOCK_READ = 2,
MOCK_WRITE = 3,
MOCK_CLOSE = 4,
};
int (*real_socket)(int, int, int);
int (*real_bind)(int, const struct sockaddr *, socklen_t);
int (*real_close)(int);
@ -68,10 +80,14 @@ ssize_t (*real_send)(int, const void *, size_t, int);
ssize_t (*real_sendto)(int, const void *, size_t, int, const struct sockaddr *, socklen_t);
ssize_t (*real_sendmsg)(int, const struct msghdr *, int);
int (*real_setsockopt)(int, int, int, const void *, socklen_t);
int (*real_open)(const char *, int, mode_t);
ssize_t (*real_read)(int, void *, size_t);
ssize_t (*real_write)(int, const void *, size_t);
static void do_init(void) {
setenv("RTPE_PRELOAD_TEST_ACTIVE", "1", 1);
p_prefix = getenv("TEST_SOCKET_PATH");
mock_peer = getenv("MOCK_PEER");
real_socket = dlsym(RTLD_NEXT, "socket");
real_bind = dlsym(RTLD_NEXT, "bind");
@ -88,6 +104,18 @@ static void do_init(void) {
real_sendto = dlsym(RTLD_NEXT, "sendto");
real_sendmsg = dlsym(RTLD_NEXT, "sendmsg");
real_setsockopt = dlsym(RTLD_NEXT, "setsockopt");
real_open = dlsym(RTLD_NEXT, "open");
real_read = dlsym(RTLD_NEXT, "read");
real_write = dlsym(RTLD_NEXT, "write");
for (unsigned int i = 0; i < MAX_MOCK_FILES; i++) {
char var[64];
sprintf(var, "MOCK_%u", i);
char *mpath = getenv(var);
if (!mpath)
break;
mock_files[i] = mpath;
}
}
static void do_exit(void) {
for (int i = 0; i < MAX_SOCKETS; i++) {
@ -909,3 +937,88 @@ do_set_warn:
do_set:
return real_setsockopt(fd, level, optname, optval, optlen);
}
int open(const char *fn, int flags, mode_t mode) {
unsigned int i;
for (i = 0; i < MAX_MOCK_FILES; i++) {
if (!mock_files[i])
break;
if (strcmp(fn, mock_files[i]))
continue;
goto found;
}
return real_open(fn, flags, mode);
found:
if (!mock_peer)
return -1;
int fd = real_socket(AF_UNIX, SOCK_DGRAM, 0);
if (fd == -1)
return -1;
struct sockaddr_un sun = { .sun_family = AF_UNIX };
assert(strlen(mock_peer) < sizeof(sun.sun_path));
strcpy(sun.sun_path, mock_peer);
int ret = real_connect(fd, (struct sockaddr *) &sun, sizeof(sun));
if (ret) {
close(fd);
return -1;
}
struct {
int msg;
char fn[sizeof(sun.sun_path)];
} m = { .msg = MOCK_OPEN };
strcpy(m.fn, fn);
ssize_t r = real_send(fd, &m, sizeof(m), 0);
assert(r == sizeof(m));
struct {
int msg;
int code;
} n;
r = real_recvfrom(fd, &n, sizeof(n), 0, NULL, NULL);
assert(r == sizeof(n));
assert(n.msg == MOCK_OPEN);
if (n.code != 0) {
real_close(fd);
return -1;
}
real_sockets[fd] = (socket_t) {
.open = 1,
.mock = 1,
};
return fd;
}
ssize_t read(int fd, void *buf, size_t len) {
if (fd < 0 || fd >= MAX_SOCKETS)
goto do_read;
socket_t *s = &real_sockets[fd];
if (!s->open || !s->mock)
goto do_read;
do_read:
return real_read(fd, buf, len);
}
ssize_t write(int fd, const void *buf, size_t len) {
if (fd < 0 || fd >= MAX_SOCKETS)
goto do_write;
socket_t *s = &real_sockets[fd];
if (!s->open || !s->mock)
goto do_write;
do_write:
return real_write(fd, buf, len);
}

Loading…
Cancel
Save