This source file includes following definitions.
- tvtojiffies
- jiffiestotv
- _getitimer
- sys_getitimer
- it_real_fn
- _setitimer
- sys_setitimer
1
2
3
4
5
6
7
8
9 #include <linux/signal.h>
10 #include <linux/sched.h>
11 #include <linux/string.h>
12 #include <linux/errno.h>
13 #include <linux/time.h>
14 #include <linux/mm.h>
15
16 #include <asm/segment.h>
17
18
19
20
21
22
23
24
25
26
27
28 static unsigned long tvtojiffies(struct timeval *value)
29 {
30 unsigned long sec = (unsigned) value->tv_sec;
31 unsigned long usec = (unsigned) value->tv_usec;
32
33 if (sec > (ULONG_MAX / HZ))
34 return ULONG_MAX;
35 usec += 1000000 / HZ - 1;
36 usec /= 1000000 / HZ;
37 return HZ*sec+usec;
38 }
39
40 static void jiffiestotv(unsigned long jiffies, struct timeval *value)
41 {
42 value->tv_usec = (jiffies % HZ) * (1000000 / HZ);
43 value->tv_sec = jiffies / HZ;
44 return;
45 }
46
47 static int _getitimer(int which, struct itimerval *value)
48 {
49 register unsigned long val, interval;
50
51 switch (which) {
52 case ITIMER_REAL:
53 interval = current->it_real_incr;
54 val = 0;
55 if (del_timer(¤t->real_timer)) {
56 unsigned long now = jiffies;
57 val = current->real_timer.expires;
58 add_timer(¤t->real_timer);
59
60 if (val <= now)
61 val = now+1;
62 val -= now;
63 }
64 break;
65 case ITIMER_VIRTUAL:
66 val = current->it_virt_value;
67 interval = current->it_virt_incr;
68 break;
69 case ITIMER_PROF:
70 val = current->it_prof_value;
71 interval = current->it_prof_incr;
72 break;
73 default:
74 return(-EINVAL);
75 }
76 jiffiestotv(val, &value->it_value);
77 jiffiestotv(interval, &value->it_interval);
78 return 0;
79 }
80
81 asmlinkage int sys_getitimer(int which, struct itimerval *value)
82 {
83 int error;
84 struct itimerval get_buffer;
85
86 if (!value)
87 return -EFAULT;
88 error = _getitimer(which, &get_buffer);
89 if (error)
90 return error;
91 error = verify_area(VERIFY_WRITE, value, sizeof(struct itimerval));
92 if (error)
93 return error;
94 memcpy_tofs(value, &get_buffer, sizeof(get_buffer));
95 return 0;
96 }
97
98 void it_real_fn(unsigned long __data)
99 {
100 struct task_struct * p = (struct task_struct *) __data;
101 unsigned long interval;
102
103 send_sig(SIGALRM, p, 1);
104 interval = p->it_real_incr;
105 if (interval) {
106 unsigned long timeout = jiffies + interval;
107
108 if (timeout < interval)
109 timeout = ULONG_MAX;
110 p->real_timer.expires = timeout;
111 add_timer(&p->real_timer);
112 }
113 }
114
115 int _setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
116 {
117 register unsigned long i, j;
118 int k;
119
120 i = tvtojiffies(&value->it_interval);
121 j = tvtojiffies(&value->it_value);
122 if (ovalue && (k = _getitimer(which, ovalue)) < 0)
123 return k;
124 switch (which) {
125 case ITIMER_REAL:
126 del_timer(¤t->real_timer);
127 current->it_real_value = j;
128 current->it_real_incr = i;
129 if (!j)
130 break;
131 i = j + jiffies;
132
133 if (i < j)
134 i = ULONG_MAX;
135 current->real_timer.expires = i;
136 add_timer(¤t->real_timer);
137 break;
138 case ITIMER_VIRTUAL:
139 if (j)
140 j++;
141 current->it_virt_value = j;
142 current->it_virt_incr = i;
143 break;
144 case ITIMER_PROF:
145 if (j)
146 j++;
147 current->it_prof_value = j;
148 current->it_prof_incr = i;
149 break;
150 default:
151 return -EINVAL;
152 }
153 return 0;
154 }
155
156 asmlinkage int sys_setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
157 {
158 int error;
159 struct itimerval set_buffer, get_buffer;
160
161 if (value) {
162 error = verify_area(VERIFY_READ, value, sizeof(*value));
163 if (error)
164 return error;
165 memcpy_fromfs(&set_buffer, value, sizeof(set_buffer));
166 } else
167 memset((char *) &set_buffer, 0, sizeof(set_buffer));
168
169 if (ovalue) {
170 error = verify_area(VERIFY_WRITE, ovalue, sizeof(struct itimerval));
171 if (error)
172 return error;
173 }
174
175 error = _setitimer(which, &set_buffer, ovalue ? &get_buffer : 0);
176 if (error || !ovalue)
177 return error;
178
179 memcpy_tofs(ovalue, &get_buffer, sizeof(get_buffer));
180 return error;
181 }