|
|
1.1 root 1: /*
2: * linux/kernel/itimer.c
3: *
1.1.1.3 ! root 4: * Copyright (C) 1992 Darren Senn
1.1 root 5: */
6:
7: /* These are all the functions necessary to implement itimers */
8:
1.1.1.3 ! root 9: #include <linux/signal.h>
1.1 root 10: #include <linux/sched.h>
1.1.1.2 root 11: #include <linux/string.h>
1.1.1.3 ! root 12: #include <linux/errno.h>
! 13: #include <linux/time.h>
1.1 root 14:
1.1.1.3 ! root 15: #include <asm/segment.h>
1.1 root 16:
17: static unsigned long tvtojiffies(struct timeval *value)
18: {
19: return((unsigned long )value->tv_sec * HZ +
20: (unsigned long )(value->tv_usec + (1000000 / HZ - 1)) /
21: (1000000 / HZ));
22: }
23:
24: static void jiffiestotv(unsigned long jiffies, struct timeval *value)
25: {
26: value->tv_usec = (jiffies % HZ) * (1000000 / HZ);
27: value->tv_sec = jiffies / HZ;
28: return;
29: }
30:
31: int _getitimer(int which, struct itimerval *value)
32: {
33: register unsigned long val, interval;
34:
35: switch (which) {
36: case ITIMER_REAL:
37: val = current->it_real_value;
38: interval = current->it_real_incr;
39: break;
40: case ITIMER_VIRTUAL:
41: val = current->it_virt_value;
42: interval = current->it_virt_incr;
43: break;
44: case ITIMER_PROF:
45: val = current->it_prof_value;
46: interval = current->it_prof_incr;
47: break;
48: default:
49: return(-EINVAL);
50: }
51: jiffiestotv(val, &value->it_value);
52: jiffiestotv(interval, &value->it_interval);
53: return(0);
54: }
55:
56: int sys_getitimer(int which, struct itimerval *value)
57: {
58: struct itimerval get_buffer;
59: int k;
60:
61: if (!value)
62: return -EFAULT;
63: k = _getitimer(which, &get_buffer);
64: if (k < 0)
65: return k;
66: verify_area(value, sizeof(struct itimerval));
67: memcpy_tofs(value, &get_buffer, sizeof(get_buffer));
68: return 0;
69: }
70:
71: int _setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
72: {
73: register unsigned long i, j;
74: int k;
75:
76: i = tvtojiffies(&value->it_interval);
77: j = tvtojiffies(&value->it_value);
78: if (ovalue && (k = _getitimer(which, ovalue)) < 0)
79: return k;
80: switch (which) {
81: case ITIMER_REAL:
82: current->it_real_value = j;
83: current->it_real_incr = i;
84: break;
85: case ITIMER_VIRTUAL:
86: current->it_virt_value = j;
87: current->it_virt_incr = i;
88: break;
89: case ITIMER_PROF:
90: current->it_prof_value = j;
91: current->it_prof_incr = i;
92: break;
93: default:
94: return -EINVAL;
95: }
96: return 0;
97: }
98:
99: int sys_setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
100: {
101: struct itimerval set_buffer, get_buffer;
102: int k;
103:
104: if (!value)
105: memset((char *) &set_buffer, 0, sizeof(set_buffer));
106: else
107: memcpy_fromfs(&set_buffer, value, sizeof(set_buffer));
108: k = _setitimer(which, &set_buffer, ovalue ? &get_buffer : 0);
109: if (k < 0 || !ovalue)
110: return k;
111: verify_area(ovalue, sizeof(struct itimerval));
112: memcpy_tofs(ovalue, &get_buffer, sizeof(get_buffer));
113: return 0;
114: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.