Пример #1
0
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
}
Пример #2
0
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();
}
Пример #3
0
Файл: fcntl03.c Проект: kraj/ltp
static void cleanup(void)
{
	if (fd > 0)
		SAFE_CLOSE(fd);
}
Пример #4
0
/* 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;
}
Пример #5
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();
}
Пример #6
0
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();
}