static void
displayClock(clockid_t clock, const char *name, bool showRes)
{
- struct timespec ts;
+ long days;
+ struct timespec ts;
if (clock_gettime(clock, &ts) == \-1) {
perror("clock_gettime");
printf("%\-15s: %10jd.%03ld (", name,
(intmax_t) ts.tv_sec, ts.tv_nsec / 1000000);
- long days = ts.tv_sec / SECS_IN_DAY;
+ days = ts.tv_sec / SECS_IN_DAY;
if (days > 0)
printf("%ld days + ", days);
static void
show_fds(void)
{
- DIR *dirp = opendir("/proc/self/fd");
+ DIR *dirp;
+ char path[PATH_MAX], target[PATH_MAX];
+ ssize_t len;
+ struct dirent *dp;
+
+ dirp = opendir("/proc/self/fd");
if (dirp == NULL) {
perror("opendir");
exit(EXIT_FAILURE);
}
for (;;) {
- struct dirent *dp = readdir(dirp);
+ dp = readdir(dirp);
if (dp == NULL)
break;
if (dp\->d_type == DT_LNK) {
- char path[PATH_MAX], target[PATH_MAX];
snprintf(path, sizeof(path), "/proc/self/fd/%s",
dp\->d_name);
- ssize_t len = readlink(path, target, sizeof(target));
+ len = readlink(path, target, sizeof(target));
printf("%s ==> %.*s\en", path, (int) len, target);
}
}
int
main(int argc, char *argv[])
{
+ int fd;
+
for (int j = 1; j < argc; j++) {
- int fd = open(argv[j], O_RDONLY);
+ fd = open(argv[j], O_RDONLY);
if (fd == \-1) {
perror(argv[j]);
exit(EXIT_FAILURE);
static void
fwait(uint32_t *futexp)
{
- long s;
+ long s;
+ const uint32_t one = 1;
/* atomic_compare_exchange_strong(ptr, oldval, newval)
atomically performs the equivalent of:
while (1) {
/* Is the futex available? */
- const uint32_t one = 1;
if (atomic_compare_exchange_strong(futexp, &one, 0))
break; /* Yes */
static void
fpost(uint32_t *futexp)
{
- long s;
+ long s;
+ const uint32_t zero = 0;
/* atomic_compare_exchange_strong() was described
in comments above. */
- const uint32_t zero = 0;
if (atomic_compare_exchange_strong(futexp, &zero, 1)) {
s = futex(futexp, FUTEX_WAKE, 1, NULL, NULL, 0);
if (s == \-1)
int
main(int argc, char *argv[])
{
- int nfds, num_open_fds;
- struct pollfd *pfds;
+ int nfds, num_open_fds, ready;
+ char buf[10];
+ ssize_t s;
+ struct pollfd *pfds;
if (argc < 2) {
fprintf(stderr, "Usage: %s file...\en", argv[0]);
open. */
while (num_open_fds > 0) {
- int ready;
-
printf("About to poll()\en");
ready = poll(pfds, nfds, \-1);
if (ready == \-1)
/* Deal with array returned by poll(). */
for (int j = 0; j < nfds; j++) {
- char buf[10];
-
if (pfds[j].revents != 0) {
printf(" fd=%d; events: %s%s%s\en", pfds[j].fd,
(pfds[j].revents & POLLIN) ? "POLLIN " : "",
(pfds[j].revents & POLLERR) ? "POLLERR " : "");
if (pfds[j].revents & POLLIN) {
- ssize_t s = read(pfds[j].fd, buf, sizeof(buf));
+ s = read(pfds[j].fd, buf, sizeof(buf));
if (s == \-1)
errExit("read");
printf(" read %zd bytes: %.*s\en",
static pid_t
targetProcess(int sockPair[2], char *argv[])
{
- pid_t targetPid = fork();
+ int notifyFd, s;
+ pid_t targetPid;
+
+ targetPid = fork();
+
if (targetPid == \-1)
errExit("fork");
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0))
errExit("prctl");
- int notifyFd = installNotifyFilter();
+ notifyFd = installNotifyFilter();
/* Pass the notification file descriptor to the tracing process over
a UNIX domain socket */
for (char **ap = argv; *ap != NULL; ap++) {
printf("\enT: about to mkdir(\e"%s\e")\en", *ap);
- int s = mkdir(*ap, 0700);
+ s = mkdir(*ap, 0700);
if (s == \-1)
perror("T: ERROR: mkdir(2)");
else
getTargetPathname(struct seccomp_notif *req, int notifyFd,
int argNum, char *path, size_t len)
{
- char procMemPath[PATH_MAX];
+ int procMemFd;
+ char procMemPath[PATH_MAX];
+ ssize_t nread;
snprintf(procMemPath, sizeof(procMemPath), "/proc/%d/mem", req\->pid);
- int procMemFd = open(procMemPath, O_RDONLY | O_CLOEXEC);
+ procMemFd = open(procMemPath, O_RDONLY | O_CLOEXEC);
if (procMemFd == \-1)
return false;
/* Read bytes at the location containing the pathname argument */
- ssize_t nread = pread(procMemFd, path, len, req\->data.args[argNum]);
+ nread = pread(procMemFd, path, len, req\->data.args[argNum]);
close(procMemFd);
struct seccomp_notif_resp **resp,
struct seccomp_notif_sizes *sizes)
{
+ size_t resp_size;
+
/* Discover the sizes of the structures that are used to receive
notifications and send notification responses, and allocate
buffers of those sizes. */
structure that are past the response size that the kernel expects,
then the supervisor is not touching an invalid memory location. */
- size_t resp_size = sizes\->seccomp_notif_resp;
+ resp_size = sizes\->seccomp_notif_resp;
if (sizeof(struct seccomp_notif_resp) > resp_size)
resp_size = sizeof(struct seccomp_notif_resp);
static void
handleNotifications(int notifyFd)
{
- struct seccomp_notif_sizes sizes;
- struct seccomp_notif *req;
- struct seccomp_notif_resp *resp;
- char path[PATH_MAX];
+ bool pathOK;
+ char path[PATH_MAX];
+ struct seccomp_notif *req;
+ struct seccomp_notif_resp *resp;
+ struct seccomp_notif_sizes sizes;
allocSeccompNotifBuffers(&req, &resp, &sizes);
exit(EXIT_FAILURE);
}
- bool pathOK = getTargetPathname(req, notifyFd, 0, path,
- sizeof(path));
+ pathOK = getTargetPathname(req, notifyFd, 0, path, sizeof(path));
/* Prepopulate some fields of the response */
static void
supervisor(int sockPair[2])
{
- int notifyFd = recvfd(sockPair[1]);
+ int notifyFd;
+
+ notifyFd = recvfd(sockPair[1]);
+
if (notifyFd == \-1)
errExit("recvfd");
int
main(int argc, char *argv[])
{
- int sockPair[2];
+ int sockPair[2];
+ struct sigaction sa;
setbuf(stdout, NULL);
/* Catch SIGCHLD when the target terminates, so that the
supervisor can also terminate. */
- struct sigaction sa;
sa.sa_handler = sigchldHandler;
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask);
static void *
fault_handler_thread(void *arg)
{
+ int nready;
+ struct pollfd pollfd;
static struct uffd_msg msg; /* Data read from userfaultfd */
static int fault_cnt = 0; /* Number of faults so far handled */
long uffd; /* userfaultfd file descriptor */
/* See what poll() tells us about the userfaultfd. */
- struct pollfd pollfd;
- int nready;
pollfd.fd = uffd;
pollfd.events = POLLIN;
nready = poll(&pollfd, 1, \-1);