OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [arch/] [parisc/] [kernel/] [signal32.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/* mostly borrowed from kernel/signal.c */
2
#include <linux/config.h>
3
#include <linux/slab.h>
4
#include <linux/module.h>
5
#include <linux/unistd.h>
6
#include <linux/smp_lock.h>
7
#include <linux/init.h>
8
#include <linux/sched.h>
9
#include <linux/types.h>
10
 
11
#include <asm/uaccess.h>
12
#include "sys32.h"
13
 
14
struct k_sigaction32 {
15
        struct sigaction32 sa;
16
};
17
 
18
typedef unsigned int old_sigset_t32;
19
 
20
static int
21
put_old_sigset32(old_sigset_t32 *up, old_sigset_t *set)
22
{
23
        old_sigset_t32 set32 = *set;
24
        return put_user(set32, up);
25
}
26
 
27
static int
28
get_old_segset32(old_sigset_t32 *up, old_sigset_t *set)
29
{
30
        old_sigset_t32 set32;
31
        int r;
32
 
33
        if ((r = get_user(set32, up)) == 0)
34
                *set = set32;
35
 
36
        return r;
37
}
38
 
39
long
40
sys32_sigpending(old_sigset_t32 *set)
41
{
42
        extern long sys_sigpending(old_sigset_t *set);
43
        old_sigset_t pending;
44
        int ret;
45
 
46
        KERNEL_SYSCALL(ret, sys_sigpending, &pending);
47
 
48
        /* can't put_user an old_sigset_t -- it is too big */
49
        if (put_old_sigset32(set, &pending))
50
                return -EFAULT;
51
 
52
        return ret;
53
}
54
 
55
int sys32_sigprocmask(int how, old_sigset_t32 *set,
56
                                 old_sigset_t32 *oset)
57
{
58
        extern int sys_sigprocmask(int how, old_sigset_t *set,
59
                                 old_sigset_t *oset);
60
        old_sigset_t s;
61
        int ret;
62
 
63
        if (set && get_old_segset32 (set, &s))
64
                return -EFAULT;
65
        KERNEL_SYSCALL(ret, sys_sigprocmask, how, set ? &s : NULL, oset ? &s : NULL);
66
        if (!ret && oset && put_old_sigset32(oset, &s))
67
                return -EFAULT;
68
        return ret;
69
}
70
 
71
static inline void
72
sigset_32to64(sigset_t *s64, sigset_t32 *s32)
73
{
74
        s64->sig[0] = s32->sig[0] | ((unsigned long)s32->sig[1] << 32);
75
}
76
 
77
static inline void
78
sigset_64to32(sigset_t32 *s32, sigset_t *s64)
79
{
80
        s32->sig[0] = s64->sig[0] & 0xffffffffUL;
81
        s32->sig[1] = (s64->sig[0] >> 32) & 0xffffffffUL;
82
}
83
 
84
static int
85
put_sigset32(sigset_t32 *up, sigset_t *set, size_t sz)
86
{
87
        sigset_t32 s;
88
 
89
        if (sz != sizeof *set) panic("put_sigset32()");
90
        sigset_64to32(&s, set);
91
 
92
        return copy_to_user(up, &s, sizeof s);
93
}
94
 
95
static int
96
get_sigset32(sigset_t32 *up, sigset_t *set, size_t sz)
97
{
98
        sigset_t32 s;
99
        int r;
100
 
101
        if (sz != sizeof *set) panic("put_sigset32()");
102
 
103
        if ((r = copy_from_user(&s, up, sz)) == 0) {
104
                sigset_32to64(set, &s);
105
        }
106
 
107
        return r;
108
}
109
 
110
int sys32_rt_sigprocmask(int how, sigset_t32 *set, sigset_t32 *oset,
111
                                    unsigned int sigsetsize)
112
{
113
        extern long sys_rt_sigprocmask(int how,
114
                                    sigset_t *set, sigset_t *oset,
115
                                   size_t sigsetsize);
116
        sigset_t old_set, new_set;
117
        int ret;
118
 
119
        if (set && get_sigset32(set, &new_set, sigsetsize))
120
                return -EFAULT;
121
 
122
        KERNEL_SYSCALL(ret, sys_rt_sigprocmask, how, set ? &new_set : NULL,
123
                                 oset ? &old_set : NULL, sigsetsize);
124
 
125
        if (!ret && oset && put_sigset32(oset, &old_set, sigsetsize))
126
                return -EFAULT;
127
 
128
        return ret;
129
}
130
 
131
 
132
int sys32_rt_sigpending(sigset_t32 *uset, unsigned int sigsetsize)
133
{
134
        int ret;
135
        sigset_t set;
136
        extern long sys_rt_sigpending(sigset_t *set, size_t sigsetsize);
137
 
138
        KERNEL_SYSCALL(ret, sys_rt_sigpending, &set, sigsetsize);
139
 
140
        if (!ret && put_sigset32(uset, &set, sigsetsize))
141
                return -EFAULT;
142
 
143
        return ret;
144
}
145
 
146
long
147
sys32_rt_sigaction(int sig, const struct sigaction32 *act, struct sigaction32 *oact,
148
                 size_t sigsetsize)
149
{
150
        struct k_sigaction32 new_sa32, old_sa32;
151
        struct k_sigaction new_sa, old_sa;
152
        int ret = -EINVAL;
153
 
154
        if (act) {
155
                if (copy_from_user(&new_sa32.sa, act, sizeof new_sa32.sa))
156
                        return -EFAULT;
157
                new_sa.sa.sa_handler = (__sighandler_t)(unsigned long)new_sa32.sa.sa_handler;
158
                new_sa.sa.sa_flags = new_sa32.sa.sa_flags;
159
                sigset_32to64(&new_sa.sa.sa_mask, &new_sa32.sa.sa_mask);
160
        }
161
 
162
        ret = do_sigaction(sig, act ? &new_sa : NULL, oact ? &old_sa : NULL);
163
 
164
        if (!ret && oact) {
165
                sigset_64to32(&old_sa32.sa.sa_mask, &old_sa.sa.sa_mask);
166
                old_sa32.sa.sa_flags = old_sa.sa.sa_flags;
167
                old_sa32.sa.sa_handler = (__sighandler_t32)(unsigned long)old_sa.sa.sa_handler;
168
                if (copy_to_user(oact, &old_sa32.sa, sizeof old_sa32.sa))
169
                        return -EFAULT;
170
        }
171
        return ret;
172
}
173
 
174
typedef struct {
175
        unsigned int ss_sp;
176
        int ss_flags;
177
        __kernel_size_t32 ss_size;
178
} stack_t32;
179
 
180
int
181
do_sigaltstack32 (const stack_t32 *uss32, stack_t32 *uoss32, unsigned long sp)
182
{
183
        stack_t32 ss32, oss32;
184
        stack_t ss, oss;
185
        stack_t *ssp = NULL, *ossp = NULL;
186
        int ret;
187
 
188
        if (uss32) {
189
                if (copy_from_user(&ss32, uss32, sizeof ss32))
190
                        return -EFAULT;
191
 
192
                ss.ss_sp = (void *)ss32.ss_sp;
193
                ss.ss_flags = ss32.ss_flags;
194
                ss.ss_size = ss32.ss_size;
195
 
196
                ssp = &ss;
197
        }
198
 
199
        if (uoss32)
200
                ossp = &oss;
201
 
202
        KERNEL_SYSCALL(ret, do_sigaltstack, ssp, ossp, sp);
203
 
204
        if (!ret && uoss32) {
205
                oss32.ss_sp = (unsigned int)(unsigned long)oss.ss_sp;
206
                oss32.ss_flags = oss.ss_flags;
207
                oss32.ss_size = oss.ss_size;
208
                if (copy_to_user(uoss32, &oss32, sizeof *uoss32))
209
                        return -EFAULT;
210
        }
211
 
212
        return ret;
213
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.