1/**
2 * @file daemon/opd_pipe.c
3 * Functions handling the $SESSIONDIR/opd_pipe FIFO special file.
4 * NOTE: This code is dealing with potentially insecure input.
5 *
6 * @remark Copyright 2008 OProfile authors
7 * @remark Read the file COPYING
8 *
9 * @author Daniel Hansel
10 */
11
12#include "opd_pipe.h"
13#include "opd_printf.h"
14#include "op_config.h"
15
16#include <stdio.h>
17#include <stdlib.h>
18#include <string.h>
19#include <fcntl.h>
20#include <unistd.h>
21#include <errno.h>
22#include <sys/stat.h>
23
24static int fifo;
25static FILE * fifo_fd = NULL;
26
27void opd_create_pipe(void)
28{
29	mode_t orig_umask = umask(0111);
30	if (mkfifo(op_pipe_file, 0666) == -1) {
31		if (errno != EEXIST) {
32			perror("oprofiled: couldn't create pipe: ");
33			exit(EXIT_FAILURE);
34		}
35	}
36	umask(orig_umask);
37}
38
39
40void opd_open_pipe(void)
41{
42	fifo = open(op_pipe_file, O_RDONLY | O_NONBLOCK);
43	if (fifo == -1) {
44		perror("oprofiled: couldn't open pipe: ");
45		exit(EXIT_FAILURE);
46	}
47}
48
49
50void opd_close_pipe(void)
51{
52	if (fifo_fd)
53		fclose(fifo_fd);
54	close(fifo);
55}
56
57
58int is_jitconv_requested(void)
59{
60	/* number of dropped (unknown) requests */
61	static long nr_drops = 0;
62	/* modulus to output only a few warnings to avoid flooding oprofiled.log */
63	static int mod_cnt_drops = 1;
64	char line[256];
65	int i, ret = 0;
66
67	/* get a file descriptor to the pipe */
68	if (!fifo_fd)
69		fifo_fd = fdopen(fifo, "r");
70
71	if (fifo_fd == NULL) {
72		perror("oprofiled: couldn't create file descriptor: ");
73		exit(EXIT_FAILURE);
74	}
75
76	/* read up to 99 lines to check for 'do_jitconv' */
77	for (i = 0; i < 99; i++) {
78		/* just break if no new line is found */
79		if (fgets(line, 256, fifo_fd) == NULL)
80			break;
81		line[strlen(line) - 1] = '\0';
82
83		if (strstr(line, "do_jitconv") != NULL) {
84			ret = 1;
85		} else {
86			nr_drops++;
87
88			if (nr_drops % mod_cnt_drops == 0) {
89				printf(
90				       "Warning: invalid pipe request received (dropped request(s): %ld)\n",
91				       nr_drops);
92				/* increase modulus to avoid flooding log file */
93				mod_cnt_drops *= 5;
94			}
95		}
96	}
97
98	return ret;
99}
100