1    	/*
2    	 * Copyright (C) 2010 Red Hat, Inc.
3    	 *
4    	 * Author: Angus Salkeld <asalkeld@redhat.com>
5    	 *
6    	 * This file is part of libqb.
7    	 *
8    	 * libqb is free software: you can redistribute it and/or modify
9    	 * it under the terms of the GNU Lesser General Public License as published by
10   	 * the Free Software Foundation, either version 2.1 of the License, or
11   	 * (at your option) any later version.
12   	 *
13   	 * libqb is distributed in the hope that it will be useful,
14   	 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15   	 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   	 * GNU Lesser General Public License for more details.
17   	 *
18   	 * You should have received a copy of the GNU Lesser General Public License
19   	 * along with libqb.  If not, see <http://www.gnu.org/licenses/>.
20   	 */
21   	#include "os_base.h"
22   	#include <sys/poll.h>
23   	
24   	#include <qb/qbdefs.h>
25   	#include <qb/qbutil.h>
26   	#include <qb/qblog.h>
27   	#include <qb/qbloop.h>
28   	
29   	static struct qb_loop *l;
30   	static qb_loop_timer_handle th;
31   	
32   	static void job_3_9(void *data) { qb_log(LOG_INFO, "%s\n", __func__); }
33   	static void job_1_2(void *data) { qb_log(LOG_INFO, "%s\n", __func__); }
34   	static void job_2_4(void *data) { qb_log(LOG_INFO, "%s\n", __func__); }
35   	static void job_3_5(void *data) { qb_log(LOG_INFO, "%s\n", __func__); }
36   	static void job_3_6(void *data) { qb_log(LOG_INFO, "%s\n", __func__); }
37   	static void job_1_1(void *data) { qb_log(LOG_INFO, "%s\n", __func__); }
38   	static void job_3_7(void *data) { qb_log(LOG_INFO, "%s\n", __func__); }
39   	static void job_2_3(void *data) { qb_log(LOG_INFO, "%s\n", __func__); }
40   	static void job_2_8(void *data) { qb_log(LOG_INFO, "%s\n", __func__); }
41   	static void job_1_9(void *data) { qb_log(LOG_INFO, "%s\n", __func__); }
42   	
43   	static void more_important_jobs(void *data)
44   	{
45   		qb_enter();
46   		qb_loop_job_add(l, QB_LOOP_HIGH, NULL, job_1_2);
47   		qb_loop_job_add(l, QB_LOOP_HIGH, NULL, job_1_9);
48   	}
49   	
50   	static int32_t handle_reconf_signal(int32_t sig, void *data)
51   	{
52   		qb_log(LOG_INFO, "signal %d", sig);
53   		return 0;
54   	}
55   	
56   	static int32_t handle_exit_signal(int32_t sig, void *data)
57   	{
58   		qb_log(LOG_INFO, "exiting (signal %d)... bye", sig);
59   		qb_loop_stop(l);
60   		return -1;
61   	}
62   	
63   	static void more_jobs(void *data)
64   	{
65   		qb_log(LOG_INFO, "%s\n", __func__);
66   		qb_loop_timer_add(l, QB_LOOP_HIGH, 3109*QB_TIME_NS_IN_MSEC, NULL, job_1_1, &th);
67   		qb_loop_job_add(l, QB_LOOP_LOW,  NULL, job_3_7);
68   		qb_loop_timer_add(l, QB_LOOP_LOW, 1000*QB_TIME_NS_IN_MSEC, NULL, more_important_jobs, &th);
69   		qb_loop_job_add(l, QB_LOOP_LOW,  NULL, job_3_7);
70   		qb_loop_timer_add(l, QB_LOOP_LOW, 2341*QB_TIME_NS_IN_MSEC, NULL, job_3_7, &th);
71   		qb_loop_timer_add(l, QB_LOOP_LOW, 900, NULL, job_3_6, &th);
72   		qb_loop_job_add(l, QB_LOOP_LOW,  NULL, job_3_5);
73   		qb_loop_timer_add(l, QB_LOOP_MED, 4000*QB_TIME_NS_IN_MSEC, NULL, more_jobs, &th);
74   		qb_loop_job_add(l, QB_LOOP_LOW,  NULL, job_3_9);
75   		qb_loop_job_add(l, QB_LOOP_HIGH, NULL, job_1_9);
76   		qb_loop_job_add(l, QB_LOOP_MED,  NULL, job_2_3);
77   	}
78   	
79   	static int32_t read_stdin(int32_t fd, int32_t revents, void *data)
80   	{
81   		char buf[100];
(1) Event tainted_data_return: Called function "read(fd, buf, 100UL)", and a possible return value may be less than zero.
(2) Event assign: Assigning: "len" = "read(fd, buf, 100UL)".
Also see events: [overflow][deref_overflow]
82   		ssize_t len = read(fd, buf, 100);
(3) Event overflow: The expression "len - 1L" is considered to have possibly overflowed.
(4) Event deref_overflow: "len - 1L", which might have overflowed, is used in a pointer index in "buf[len - 1L]".
Also see events: [tainted_data_return][assign]
83   		buf[len-1] = '\0';
84   		qb_log(LOG_INFO, "typed > \"%s\"\n", buf);
85   		if (strcmp(buf, "more") == 0) {
86   			more_jobs(NULL);
87   		}
88   		qb_loop_job_add(l, QB_LOOP_LOW,  NULL, job_3_9);
89   		return 0;
90   	}
91   	
92   	int main(int argc, char * argv[])
93   	{
94   		qb_loop_signal_handle sh;
95   	
96   		qb_log_init("loop", LOG_USER, LOG_EMERG);
97   		qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_FALSE);
98   		qb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_ADD,
99   				  QB_LOG_FILTER_FILE, "*", LOG_DEBUG);
100  		qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_ENABLED, QB_TRUE);
101  	
102  		l = qb_loop_create();
103  	
104  		qb_loop_job_add(l, QB_LOOP_LOW,  NULL, job_3_9);
105  		qb_loop_job_add(l, QB_LOOP_LOW,  NULL, job_2_4);
106  		qb_loop_job_add(l, QB_LOOP_HIGH, NULL, job_1_2);
107  		qb_loop_job_add(l, QB_LOOP_MED,  NULL, job_3_7);
108  	/*
109  	 * 	qb_loop_timer_add(l, QB_LOOP_HIGH, 40*QB_TIME_NS_IN_MSEC, NULL, more_jobs, &th);
110  	 */
111  		qb_loop_job_add(l, QB_LOOP_MED,  NULL, job_2_8);
112  		qb_loop_job_add(l, QB_LOOP_LOW,  NULL, job_3_6);
113  	
114  		qb_loop_poll_add(l, QB_LOOP_LOW, 0, POLLIN | POLLPRI | POLLNVAL,
115  				     NULL, read_stdin);
116  	
117  		qb_loop_signal_add(l, QB_LOOP_MED, SIGINT, NULL, handle_exit_signal, &sh);
118  		qb_loop_signal_add(l, QB_LOOP_MED, SIGSEGV, NULL, handle_exit_signal, &sh);
119  		qb_loop_signal_add(l, QB_LOOP_MED, SIGHUP, NULL, handle_reconf_signal, &sh);
120  	
121  		qb_loop_run(l);
122  		return 0;
123  	}
124  	
125  	
126