tools/testing/selftests/ptrace/peeksiginfo.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/ptrace/peeksiginfo.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/ptrace/peeksiginfo.c
Extension
.c
Size
4743 bytes
Lines
220
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

if (ret == -1) {
			err("ptrace() failed: %m\n");
			goto out;
		}

		if (ret == 0)
			break;

		for (j = 0; j < ret; j++, i++) {
			if (siginfo[j].si_code == si_code &&
			    siginfo[j].si_int == i)
				continue;

			err("%d: Wrong siginfo i=%d si_code=%d si_int=%d\n",
			     shared, i, siginfo[j].si_code, siginfo[j].si_int);
			goto out;
		}
	}

	if (i != SIGNR) {
		err("Only %d signals were read\n", i);
		goto out;
	}

	exit_code = 0;
out:
	return exit_code;
}

int main(int argc, char *argv[])
{
	siginfo_t siginfo;
	int i, exit_code = 1;
	sigset_t blockmask;
	pid_t child;

	sigemptyset(&blockmask);
	sigaddset(&blockmask, SIGRTMIN);
	sigprocmask(SIG_BLOCK, &blockmask, NULL);

	child = fork();
	if (child == -1) {
		err("fork() failed: %m");
		return 1;
	} else if (child == 0) {
		pid_t ppid = getppid();
		while (1) {
			if (ppid != getppid())
				break;
			sleep(1);
		}
		return 1;
	}

	/* Send signals in process-wide and per-thread queues */
	for (i = 0; i < SIGNR; i++) {
		siginfo.si_code = TEST_SICODE_SHARE;
		siginfo.si_int = i;
		sys_rt_sigqueueinfo(child, SIGRTMIN, &siginfo);

		siginfo.si_code = TEST_SICODE_PRIV;
		siginfo.si_int = i;
		sys_rt_tgsigqueueinfo(child, child, SIGRTMIN, &siginfo);
	}

	if (sys_ptrace(PTRACE_ATTACH, child, NULL, NULL) == -1)
		return 1;

	waitpid(child, NULL, 0);

	/* Dump signals one by one*/
	if (check_direct_path(child, 0, 1))
		goto out;
	/* Dump all signals for one call */
	if (check_direct_path(child, 0, SIGNR))
		goto out;

	/*
	 * Dump signal from the process-wide queue.
	 * The number of signals is not multiple to the buffer size
	 */
	if (check_direct_path(child, 1, 3))
		goto out;

	if (check_error_paths(child))
		goto out;

	printf("PASS\n");
	exit_code = 0;
out:

Annotation

Implementation Notes