Skip to content

Instantly share code, notes, and snippets.

@PixelyIon
Created December 13, 2023 19:25
Show Gist options
  • Save PixelyIon/d625941dfc30531670286821b90891b8 to your computer and use it in GitHub Desktop.
Save PixelyIon/d625941dfc30531670286821b90891b8 to your computer and use it in GitHub Desktop.
A wrapper loaded via `LD_PRELOAD` for redirecting `STDOUT`/`STDERR` of an application to a server
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/socket.h>
#include <string.h>
void procwrap_init(int argc, char **argv, char **) {
const char *fdStr{getenv("LOG_SOCKFD")};
if (fdStr == nullptr)
return;
int fd{};
if (sscanf(fdStr, "%d", &fd) <= 0 || fd < 0)
return;
int stdoutPipe[2], stderrPipe[2];
if (pipe(stdoutPipe) != 0 || pipe(stderrPipe) != 0)
return;
dup2(stdoutPipe[1], STDOUT_FILENO);
close(stdoutPipe[1]);
dup2(stderrPipe[1], STDERR_FILENO);
close(stderrPipe[1]);
int pid{getpid()};
iovec pidVec{
.iov_base = &pid,
.iov_len = sizeof(pid)
};
char *name{basename(argv[0])};
iovec nameVec{
.iov_base = name,
.iov_len = strlen(name)
};
iovec iov[2]{pidVec, nameVec};
char cmsgbuf[CMSG_SPACE(sizeof(int) * 2)];
*reinterpret_cast<struct cmsghdr *>(cmsgbuf) = {
.cmsg_len = CMSG_LEN(sizeof(int) * 2),
.cmsg_level = SOL_SOCKET,
.cmsg_type = SCM_RIGHTS
};
int *fdptr{reinterpret_cast<int *>(CMSG_DATA(cmsgbuf))};
fdptr[0] = stdoutPipe[0];
fdptr[1] = stderrPipe[0];
struct msghdr msg{
.msg_iov = iov,
.msg_iovlen = 2,
.msg_control = cmsgbuf,
.msg_controllen = sizeof(cmsgbuf)
};
sendmsg(fd, &msg, 0);
close(stdoutPipe[0]);
close(stderrPipe[0]);
}
__attribute__((section(".init_array"))) void (*p_procwrap_init)(int, char **, char **) = &procwrap_init;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment