162306a36Sopenharmony_ci#include <stdbool.h>
262306a36Sopenharmony_ci#include <stdio.h>
362306a36Sopenharmony_ci#include <unistd.h>
462306a36Sopenharmony_ci#include <errno.h>
562306a36Sopenharmony_ci#include <sys/types.h>
662306a36Sopenharmony_ci#include <sys/stat.h>
762306a36Sopenharmony_ci#include <fcntl.h>
862306a36Sopenharmony_ci#include <stdlib.h>
962306a36Sopenharmony_ci#include <signal.h>
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#define _SDT_HAS_SEMAPHORES 1
1262306a36Sopenharmony_ci#include "sdt.h"
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci#define SEC(name) __attribute__((section(name), used))
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci#define BUF_SIZE 256
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci/* defined in urandom_read_aux.c */
1962306a36Sopenharmony_civoid urand_read_without_sema(int iter_num, int iter_cnt, int read_sz);
2062306a36Sopenharmony_ci/* these are coming from urandom_read_lib{1,2}.c */
2162306a36Sopenharmony_civoid urandlib_read_with_sema(int iter_num, int iter_cnt, int read_sz);
2262306a36Sopenharmony_civoid urandlib_read_without_sema(int iter_num, int iter_cnt, int read_sz);
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ciunsigned short urand_read_with_sema_semaphore SEC(".probes");
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_cistatic __attribute__((noinline))
2762306a36Sopenharmony_civoid urandom_read(int fd, int count)
2862306a36Sopenharmony_ci{
2962306a36Sopenharmony_ci	char buf[BUF_SIZE];
3062306a36Sopenharmony_ci	int i;
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci	for (i = 0; i < count; ++i) {
3362306a36Sopenharmony_ci		read(fd, buf, BUF_SIZE);
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci		/* trigger USDTs defined in executable itself */
3662306a36Sopenharmony_ci		urand_read_without_sema(i, count, BUF_SIZE);
3762306a36Sopenharmony_ci		STAP_PROBE3(urand, read_with_sema, i, count, BUF_SIZE);
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci		/* trigger USDTs defined in shared lib */
4062306a36Sopenharmony_ci		urandlib_read_without_sema(i, count, BUF_SIZE);
4162306a36Sopenharmony_ci		urandlib_read_with_sema(i, count, BUF_SIZE);
4262306a36Sopenharmony_ci	}
4362306a36Sopenharmony_ci}
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_cistatic volatile bool parent_ready;
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_cistatic void handle_sigpipe(int sig)
4862306a36Sopenharmony_ci{
4962306a36Sopenharmony_ci	parent_ready = true;
5062306a36Sopenharmony_ci}
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ciint main(int argc, char *argv[])
5362306a36Sopenharmony_ci{
5462306a36Sopenharmony_ci	int fd = open("/dev/urandom", O_RDONLY);
5562306a36Sopenharmony_ci	int count = 4;
5662306a36Sopenharmony_ci	bool report_pid = false;
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci	if (fd < 0)
5962306a36Sopenharmony_ci		return 1;
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci	if (argc >= 2)
6262306a36Sopenharmony_ci		count = atoi(argv[1]);
6362306a36Sopenharmony_ci	if (argc >= 3) {
6462306a36Sopenharmony_ci		report_pid = true;
6562306a36Sopenharmony_ci		/* install SIGPIPE handler to catch when parent closes their
6662306a36Sopenharmony_ci		 * end of the pipe (on the other side of our stdout)
6762306a36Sopenharmony_ci		 */
6862306a36Sopenharmony_ci		signal(SIGPIPE, handle_sigpipe);
6962306a36Sopenharmony_ci	}
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci	/* report PID and wait for parent process to send us "signal" by
7262306a36Sopenharmony_ci	 * closing stdout
7362306a36Sopenharmony_ci	 */
7462306a36Sopenharmony_ci	if (report_pid) {
7562306a36Sopenharmony_ci		while (!parent_ready) {
7662306a36Sopenharmony_ci			fprintf(stdout, "%d\n", getpid());
7762306a36Sopenharmony_ci			fflush(stdout);
7862306a36Sopenharmony_ci		}
7962306a36Sopenharmony_ci		/* at this point stdout is closed, parent process knows our
8062306a36Sopenharmony_ci		 * PID and is ready to trace us
8162306a36Sopenharmony_ci		 */
8262306a36Sopenharmony_ci	}
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci	urandom_read(fd, count);
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci	close(fd);
8762306a36Sopenharmony_ci	return 0;
8862306a36Sopenharmony_ci}
89