bool NamedPipe::Open(const String& pipeName, bool isServer) { #ifdef __EMSCRIPTEN__ URHO3D_LOGERROR("Opening a named pipe not supported on Web platform"); return false; #else URHO3D_PROFILE(OpenNamedPipe); Close(); isServer_ = false; String serverReadName = pipePath + pipeName + "SR"; String clientReadName = pipePath + pipeName + "CR"; // Make sure SIGPIPE is ignored and will not lead to process termination signal(SIGPIPE, SIG_IGN); if (isServer) { mkfifo(serverReadName.CString(), 0660); mkfifo(clientReadName.CString(), 0660); readHandle_ = open(serverReadName.CString(), O_RDONLY | O_NDELAY); writeHandle_ = open(clientReadName.CString(), O_WRONLY | O_NDELAY); if (readHandle_ == -1 && writeHandle_ == -1) { URHO3D_LOGERROR("Failed to create named pipe " + pipeName); SAFE_CLOSE(readHandle_); SAFE_CLOSE(writeHandle_); unlink(serverReadName.CString()); unlink(clientReadName.CString()); return false; } else { URHO3D_LOGDEBUG("Created named pipe " + pipeName); pipeName_ = pipeName; isServer_ = true; return true; } } else { readHandle_ = open(clientReadName.CString(), O_RDONLY | O_NDELAY); writeHandle_ = open(serverReadName.CString(), O_WRONLY | O_NDELAY); if (readHandle_ == -1 && writeHandle_ == -1) { URHO3D_LOGERROR("Failed to connect to named pipe " + pipeName); SAFE_CLOSE(readHandle_); SAFE_CLOSE(writeHandle_); return false; } else { URHO3D_LOGDEBUG("Connected to named pipe " + pipeName); pipeName_ = pipeName; return true; } } #endif }
int main(int ac, char **av) { int lc; tst_parse_opts(ac, av, NULL, NULL); setup(); for (lc = 0; TEST_LOOPING(lc); lc++) { int ret, len, i = 0, test_num = 0; tst_count = 0; if (fanotify_mark(fd_notify, FAN_MARK_ADD, FAN_ACCESS | FAN_MODIFY | FAN_CLOSE | FAN_OPEN, AT_FDCWD, fname) < 0) { tst_brkm(TBROK | TERRNO, cleanup, "fanotify_mark (%d, FAN_MARK_ADD, FAN_ACCESS | " "FAN_MODIFY | FAN_CLOSE | FAN_OPEN, AT_FDCWD, %s) " "failed", fd_notify, fname); } /* * generate sequence of events */ fd = SAFE_OPEN(cleanup, fname, O_RDONLY); event_set[tst_count] = FAN_OPEN; tst_count++; SAFE_READ(cleanup, 0, fd, buf, BUF_SIZE); event_set[tst_count] = FAN_ACCESS; tst_count++; SAFE_CLOSE(cleanup, fd); event_set[tst_count] = FAN_CLOSE_NOWRITE; tst_count++; /* * Get list of events so far. We get events here to avoid * merging of following events with the previous ones. */ ret = SAFE_READ(cleanup, 0, fd_notify, event_buf, EVENT_BUF_LEN); len = ret; fd = SAFE_OPEN(cleanup, fname, O_RDWR | O_CREAT, 0700); event_set[tst_count] = FAN_OPEN; tst_count++; SAFE_WRITE(cleanup, 1, fd, fname, strlen(fname)); event_set[tst_count] = FAN_MODIFY; tst_count++; SAFE_CLOSE(cleanup, fd); event_set[tst_count] = FAN_CLOSE_WRITE; tst_count++; /* * get another list of events */ ret = SAFE_READ(cleanup, 0, fd_notify, event_buf + len, EVENT_BUF_LEN - len); len += ret; /* * Ignore mask testing */ /* Ignore access events */ if (fanotify_mark(fd_notify, FAN_MARK_ADD | FAN_MARK_IGNORED_MASK, FAN_ACCESS, AT_FDCWD, fname) < 0) { tst_brkm(TBROK | TERRNO, cleanup, "fanotify_mark (%d, FAN_MARK_ADD | " "FAN_MARK_IGNORED_MASK, FAN_ACCESS, " "AT_FDCWD, %s) failed", fd_notify, fname); } fd = SAFE_OPEN(cleanup, fname, O_RDWR); event_set[tst_count] = FAN_OPEN; tst_count++; /* This event should be ignored */ SAFE_READ(cleanup, 0, fd, buf, BUF_SIZE); /* * get another list of events to verify the last one got ignored */ ret = SAFE_READ(cleanup, 0, fd_notify, event_buf + len, EVENT_BUF_LEN - len); len += ret; lseek(fd, 0, SEEK_SET); /* Generate modify event to clear ignore mask */ SAFE_WRITE(cleanup, 1, fd, fname, 1); event_set[tst_count] = FAN_MODIFY; tst_count++; /* * This event shouldn't be ignored because previous modification * should have removed the ignore mask */ SAFE_READ(cleanup, 0, fd, buf, BUF_SIZE); event_set[tst_count] = FAN_ACCESS; tst_count++; SAFE_CLOSE(cleanup, fd); event_set[tst_count] = FAN_CLOSE_WRITE; tst_count++; /* Read events to verify previous access was properly generated */ ret = SAFE_READ(cleanup, 0, fd_notify, event_buf + len, EVENT_BUF_LEN - len); len += ret; /* * Now ignore open & close events regardless of file * modifications */ if (fanotify_mark(fd_notify, FAN_MARK_ADD | FAN_MARK_IGNORED_MASK | FAN_MARK_IGNORED_SURV_MODIFY, FAN_OPEN | FAN_CLOSE, AT_FDCWD, fname) < 0) { tst_brkm(TBROK | TERRNO, cleanup, "fanotify_mark (%d, FAN_MARK_ADD | " "FAN_MARK_IGNORED_MASK | " "FAN_MARK_IGNORED_SURV_MODIFY, FAN_OPEN | " "FAN_CLOSE, AT_FDCWD, %s) failed", fd_notify, fname); } /* This event should be ignored */ fd = SAFE_OPEN(cleanup, fname, O_RDWR); SAFE_WRITE(cleanup, 1, fd, fname, 1); event_set[tst_count] = FAN_MODIFY; tst_count++; /* This event should be still ignored */ SAFE_CLOSE(cleanup, fd); /* This event should still be ignored */ fd = SAFE_OPEN(cleanup, fname, O_RDWR); /* Read events to verify open & close were ignored */ ret = SAFE_READ(cleanup, 0, fd_notify, event_buf + len, EVENT_BUF_LEN - len); len += ret; /* Now remove open and close from ignored mask */ if (fanotify_mark(fd_notify, FAN_MARK_REMOVE | FAN_MARK_IGNORED_MASK, FAN_OPEN | FAN_CLOSE, AT_FDCWD, fname) < 0) { tst_brkm(TBROK | TERRNO, cleanup, "fanotify_mark (%d, FAN_MARK_REMOVE | " "FAN_MARK_IGNORED_MASK, FAN_OPEN | " "FAN_CLOSE, AT_FDCWD, %s) failed", fd_notify, fname); } SAFE_CLOSE(cleanup, fd); event_set[tst_count] = FAN_CLOSE_WRITE; tst_count++; /* Read events to verify close was generated */ ret = SAFE_READ(cleanup, 0, fd_notify, event_buf + len, EVENT_BUF_LEN - len); len += ret; if (TST_TOTAL != tst_count) { tst_brkm(TBROK, cleanup, "TST_TOTAL (%d) and tst_count (%d) are not " "equal", TST_TOTAL, tst_count); } tst_count = 0; /* * check events */ while (i < len) { struct fanotify_event_metadata *event; event = (struct fanotify_event_metadata *)&event_buf[i]; if (test_num >= TST_TOTAL) { tst_resm(TFAIL, "get unnecessary event: mask=%llx " "pid=%u fd=%u", (unsigned long long)event->mask, (unsigned)event->pid, event->fd); } else if (!(event->mask & event_set[test_num])) { tst_resm(TFAIL, "get event: mask=%llx (expected %llx) " "pid=%u fd=%u", (unsigned long long)event->mask, event_set[test_num], (unsigned)event->pid, event->fd); } else if (event->pid != getpid()) { tst_resm(TFAIL, "get event: mask=%llx pid=%u " "(expected %u) fd=%u", (unsigned long long)event->mask, (unsigned)event->pid, (unsigned)getpid(), event->fd); } else { if (event->fd == -2) goto pass; ret = read(event->fd, buf, BUF_SIZE); if (ret != strlen(fname)) { tst_resm(TFAIL, "cannot read from returned fd " "of event: mask=%llx pid=%u " "fd=%u ret=%d (errno=%d)", (unsigned long long)event->mask, (unsigned)event->pid, event->fd, ret, errno); } else if (memcmp(buf, fname, strlen(fname))) { tst_resm(TFAIL, "wrong data read from returned fd " "of event: mask=%llx pid=%u " "fd=%u", (unsigned long long)event->mask, (unsigned)event->pid, event->fd); } else { pass: tst_resm(TPASS, "get event: mask=%llx pid=%u fd=%u", (unsigned long long)event->mask, (unsigned)event->pid, event->fd); } } /* * We have verified the data now so close fd and * invalidate it so that we don't check it again * unnecessarily */ close(event->fd); event->fd = -2; event->mask &= ~event_set[test_num]; /* No events left in current mask? Go for next event */ if (event->mask == 0) { i += event->event_len; } test_num++; } for (; test_num < TST_TOTAL; test_num++) { tst_resm(TFAIL, "didn't get event: mask=%llx", event_set[test_num]); } /* Remove mark to clear FAN_MARK_IGNORED_SURV_MODIFY */ if (fanotify_mark(fd_notify, FAN_MARK_REMOVE, FAN_ACCESS | FAN_MODIFY | FAN_CLOSE | FAN_OPEN, AT_FDCWD, fname) < 0) { tst_brkm(TBROK | TERRNO, cleanup, "fanotify_mark (%d, FAN_MARK_REMOVE, FAN_ACCESS | " "FAN_MODIFY | FAN_CLOSE | FAN_OPEN, AT_FDCWD, %s) " "failed", fd_notify, fname); } } cleanup(); tst_exit(); }
static void cleanup(void) { if (fd > 0) SAFE_CLOSE(fd); }
/* read_testfile - mmap testfile and read every page. * This functions measures how many I/O and time it takes to fully * read contents of test file. * * @do_readahead: call readahead prior to reading file content? * @fname: name of file to test * @fsize: how many bytes to read/mmap * @read_bytes: returns difference of bytes read, parsed from /proc/<pid>/io * @usec: returns how many microsecond it took to go over fsize bytes * @cached: returns cached kB from /proc/meminfo */ static int read_testfile(struct tcase *tc, int do_readahead, const char *fname, size_t fsize, unsigned long *read_bytes, long long *usec, unsigned long *cached) { int fd; size_t i = 0; long read_bytes_start; unsigned char *p, tmp; off_t offset = 0; fd = SAFE_OPEN(fname, O_RDONLY); if (do_readahead) { do { TEST(tc->readahead(fd, offset, fsize - offset)); if (TST_RET != 0) { SAFE_CLOSE(fd); return TST_ERR; } i++; offset += readahead_length; } while ((size_t)offset < fsize); tst_res(TINFO, "readahead calls made: %zu", i); *cached = get_cached_size(); /* offset of file shouldn't change after readahead */ offset = SAFE_LSEEK(fd, 0, SEEK_CUR); if (offset == 0) tst_res(TPASS, "offset is still at 0 as expected"); else tst_res(TFAIL, "offset has changed to: %lu", offset); } tst_timer_start(CLOCK_MONOTONIC); read_bytes_start = get_bytes_read(); p = SAFE_MMAP(NULL, fsize, PROT_READ, MAP_SHARED | MAP_POPULATE, fd, 0); /* for old kernels, where MAP_POPULATE doesn't work, touch each page */ tmp = 0; for (i = 0; i < fsize; i += pagesize) tmp = tmp ^ p[i]; /* prevent gcc from optimizing out loop above */ if (tmp != 0) tst_brk(TBROK, "This line should not be reached"); if (!do_readahead) *cached = get_cached_size(); SAFE_MUNMAP(p, fsize); *read_bytes = get_bytes_read() - read_bytes_start; tst_timer_stop(); *usec = tst_timer_elapsed_us(); SAFE_CLOSE(fd); return 0; }
int main(int ac, char **av) { int lc, i; char *msg; int len; msg = parse_opts(ac, av, NULL, NULL); if (msg != NULL) tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); setup(); for (lc = 0; TEST_LOOPING(lc); lc++) { /* * generate events */ for (i = 0; i < MAX_EVENTS + 1; i++) { sprintf(fname, "fname_%d", i); fd = SAFE_OPEN(cleanup, fname, O_RDWR | O_CREAT, 0644); SAFE_CLOSE(cleanup, fd); } while (1) { /* * get list on events */ len = read(fd_notify, &event, sizeof(event)); if (len < 0) { if (errno == -EAGAIN) { tst_resm(TFAIL, "Overflow event not " "generated!\n"); break; } tst_brkm(TBROK | TERRNO, cleanup, "read of notification event failed"); break; } if (event.fd != FAN_NOFD) close(event.fd); /* * check events */ if (event.mask != FAN_OPEN && event.mask != FAN_Q_OVERFLOW) { tst_resm(TFAIL, "get event: mask=%llx (expected %llx)" "pid=%u fd=%d", (unsigned long long)event.mask, (unsigned long long)FAN_OPEN, (unsigned)event.pid, event.fd); break; } if (event.mask == FAN_Q_OVERFLOW) { if (event.fd != FAN_NOFD) { tst_resm(TFAIL, "invalid overflow event: " "mask=%llx pid=%u fd=%d", (unsigned long long)event.mask, (unsigned)event.pid, event.fd); break; } tst_resm(TPASS, "get event: mask=%llx pid=%u fd=%d", (unsigned long long)event.mask, (unsigned)event.pid, event.fd); break; } } } cleanup(); tst_exit(); }
int main(int argc, char *argv[]) { pid_t cpid2; char path[BUFSIZ]; int lc; int fd; int ret; tst_parse_opts(argc, argv, NULL, NULL); setup(); for (lc = 0; TEST_LOOPING(lc); lc++) { tst_count = 0; parentuid = geteuid(); parentgid = getegid(); cpid1 = ltp_clone_quick(CLONE_NEWUSER | SIGCHLD, (void *)child_fn1, NULL); if (cpid1 < 0) tst_brkm(TBROK | TERRNO, cleanup, "cpid1 clone failed"); cpid2 = ltp_clone_quick(CLONE_NEWUSER | SIGCHLD, (void *)child_fn2, NULL); if (cpid2 < 0) tst_brkm(TBROK | TERRNO, cleanup, "cpid2 clone failed"); if (access("/proc/self/setgroups", F_OK) == 0) { sprintf(path, "/proc/%d/setgroups", cpid1); fd = SAFE_OPEN(cleanup, path, O_WRONLY, 0644); SAFE_WRITE(cleanup, 1, fd, "deny", 4); SAFE_CLOSE(cleanup, fd); /* If the setgroups file has the value "deny", * then the setgroups(2) system call can't * subsequently be reenabled (by writing "allow" to * the file) in this user namespace. (Attempts to * do so will fail with the error EPERM.) */ /* test that setgroups can't be re-enabled */ fd = SAFE_OPEN(cleanup, path, O_WRONLY, 0644); ret = write(fd, "allow", 5); if (ret != -1) { tst_brkm(TBROK | TERRNO, cleanup, "write action should fail"); } else if (errno != EPERM) { tst_brkm(TBROK | TERRNO, cleanup, "unexpected error: \n"); } SAFE_CLOSE(cleanup, fd); tst_resm(TPASS, "setgroups can't be re-enabled"); sprintf(path, "/proc/%d/setgroups", cpid2); fd = SAFE_OPEN(cleanup, path, O_WRONLY, 0644); SAFE_WRITE(cleanup, 1, fd, "deny", 4); SAFE_CLOSE(cleanup, fd); } updatemap(cpid1, UID_MAP, CHILD1UID, parentuid, cleanup); updatemap(cpid2, UID_MAP, CHILD2UID, parentuid, cleanup); updatemap(cpid1, GID_MAP, CHILD1GID, parentgid, cleanup); updatemap(cpid2, GID_MAP, CHILD2GID, parentgid, cleanup); TST_SAFE_CHECKPOINT_WAKE_AND_WAIT(cleanup, 1); tst_record_childstatus(cleanup, cpid1); tst_record_childstatus(cleanup, cpid2); } cleanup(); tst_exit(); }