Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
33dd955d
R
raspberrypi-kernel
项目概览
openeuler
/
raspberrypi-kernel
通知
13
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
raspberrypi-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
33dd955d
编写于
5月 27, 2017
作者:
A
Al Viro
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'work.sys_wait' into misc.alpha
上级
9ba3eb51
92ebce5a
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
188 addition
and
258 deletion
+188
-258
arch/alpha/kernel/osf_sys.c
arch/alpha/kernel/osf_sys.c
+14
-37
arch/x86/include/asm/uaccess.h
arch/x86/include/asm/uaccess.h
+1
-1
include/linux/resource.h
include/linux/resource.h
+1
-1
include/linux/sched/task.h
include/linux/sched/task.h
+2
-0
kernel/compat.c
kernel/compat.c
+0
-66
kernel/exit.c
kernel/exit.c
+164
-143
kernel/sys.c
kernel/sys.c
+6
-10
未找到文件。
arch/alpha/kernel/osf_sys.c
浏览文件 @
33dd955d
...
@@ -1178,46 +1178,23 @@ SYSCALL_DEFINE2(osf_getrusage, int, who, struct rusage32 __user *, ru)
...
@@ -1178,46 +1178,23 @@ SYSCALL_DEFINE2(osf_getrusage, int, who, struct rusage32 __user *, ru)
SYSCALL_DEFINE4
(
osf_wait4
,
pid_t
,
pid
,
int
__user
*
,
ustatus
,
int
,
options
,
SYSCALL_DEFINE4
(
osf_wait4
,
pid_t
,
pid
,
int
__user
*
,
ustatus
,
int
,
options
,
struct
rusage32
__user
*
,
ur
)
struct
rusage32
__user
*
,
ur
)
{
{
struct
rusage
r
;
long
ret
,
err
;
unsigned
int
status
=
0
;
unsigned
int
status
=
0
;
mm_segment_t
old_fs
;
struct
rusage
r
;
long
err
=
kernel_wait4
(
pid
,
&
status
,
options
,
&
r
);
if
(
err
<=
0
)
return
err
;
if
(
put_user
(
status
,
ustatus
))
return
-
EFAULT
;
if
(
!
ur
)
if
(
!
ur
)
return
sys_wait4
(
pid
,
ustatus
,
options
,
NULL
);
return
err
;
if
(
put_tv32
(
&
ur
->
ru_utime
,
&
r
.
ru_utime
))
old_fs
=
get_fs
();
set_fs
(
KERNEL_DS
);
ret
=
sys_wait4
(
pid
,
(
unsigned
int
__user
*
)
&
status
,
options
,
(
struct
rusage
__user
*
)
&
r
);
set_fs
(
old_fs
);
if
(
!
access_ok
(
VERIFY_WRITE
,
ur
,
sizeof
(
*
ur
)))
return
-
EFAULT
;
return
-
EFAULT
;
if
(
put_tv32
(
&
ur
->
ru_stime
,
&
r
.
ru_stime
))
err
=
0
;
return
-
EFAULT
;
err
|=
put_user
(
status
,
ustatus
);
if
(
copy_to_user
(
&
ur
->
ru_maxrss
,
&
r
.
ru_maxrss
,
err
|=
__put_user
(
r
.
ru_utime
.
tv_sec
,
&
ur
->
ru_utime
.
tv_sec
);
sizeof
(
struct
rusage32
)
-
offsetof
(
struct
rusage32
,
ru_maxrss
)))
err
|=
__put_user
(
r
.
ru_utime
.
tv_usec
,
&
ur
->
ru_utime
.
tv_usec
);
return
-
EFAULT
;
err
|=
__put_user
(
r
.
ru_stime
.
tv_sec
,
&
ur
->
ru_stime
.
tv_sec
);
return
err
;
err
|=
__put_user
(
r
.
ru_stime
.
tv_usec
,
&
ur
->
ru_stime
.
tv_usec
);
err
|=
__put_user
(
r
.
ru_maxrss
,
&
ur
->
ru_maxrss
);
err
|=
__put_user
(
r
.
ru_ixrss
,
&
ur
->
ru_ixrss
);
err
|=
__put_user
(
r
.
ru_idrss
,
&
ur
->
ru_idrss
);
err
|=
__put_user
(
r
.
ru_isrss
,
&
ur
->
ru_isrss
);
err
|=
__put_user
(
r
.
ru_minflt
,
&
ur
->
ru_minflt
);
err
|=
__put_user
(
r
.
ru_majflt
,
&
ur
->
ru_majflt
);
err
|=
__put_user
(
r
.
ru_nswap
,
&
ur
->
ru_nswap
);
err
|=
__put_user
(
r
.
ru_inblock
,
&
ur
->
ru_inblock
);
err
|=
__put_user
(
r
.
ru_oublock
,
&
ur
->
ru_oublock
);
err
|=
__put_user
(
r
.
ru_msgsnd
,
&
ur
->
ru_msgsnd
);
err
|=
__put_user
(
r
.
ru_msgrcv
,
&
ur
->
ru_msgrcv
);
err
|=
__put_user
(
r
.
ru_nsignals
,
&
ur
->
ru_nsignals
);
err
|=
__put_user
(
r
.
ru_nvcsw
,
&
ur
->
ru_nvcsw
);
err
|=
__put_user
(
r
.
ru_nivcsw
,
&
ur
->
ru_nivcsw
);
return
err
?
err
:
ret
;
}
}
/*
/*
...
...
arch/x86/include/asm/uaccess.h
浏览文件 @
33dd955d
...
@@ -703,7 +703,7 @@ extern struct movsl_mask {
...
@@ -703,7 +703,7 @@ extern struct movsl_mask {
#define unsafe_put_user(x, ptr, err_label) \
#define unsafe_put_user(x, ptr, err_label) \
do { \
do { \
int __pu_err; \
int __pu_err; \
__put_user_size((x), (ptr), sizeof(*(ptr)), __pu_err, -EFAULT); \
__put_user_size((
__typeof__(*(ptr)))(
x), (ptr), sizeof(*(ptr)), __pu_err, -EFAULT); \
if (unlikely(__pu_err)) goto err_label; \
if (unlikely(__pu_err)) goto err_label; \
} while (0)
} while (0)
...
...
include/linux/resource.h
浏览文件 @
33dd955d
...
@@ -6,7 +6,7 @@
...
@@ -6,7 +6,7 @@
struct
task_struct
;
struct
task_struct
;
int
getrusage
(
struct
task_struct
*
p
,
int
who
,
struct
rusage
__user
*
ru
);
void
getrusage
(
struct
task_struct
*
p
,
int
who
,
struct
rusage
*
ru
);
int
do_prlimit
(
struct
task_struct
*
tsk
,
unsigned
int
resource
,
int
do_prlimit
(
struct
task_struct
*
tsk
,
unsigned
int
resource
,
struct
rlimit
*
new_rlim
,
struct
rlimit
*
old_rlim
);
struct
rlimit
*
new_rlim
,
struct
rlimit
*
old_rlim
);
...
...
include/linux/sched/task.h
浏览文件 @
33dd955d
...
@@ -9,6 +9,7 @@
...
@@ -9,6 +9,7 @@
#include <linux/sched.h>
#include <linux/sched.h>
struct
task_struct
;
struct
task_struct
;
struct
rusage
;
union
thread_union
;
union
thread_union
;
/*
/*
...
@@ -74,6 +75,7 @@ extern long _do_fork(unsigned long, unsigned long, unsigned long, int __user *,
...
@@ -74,6 +75,7 @@ extern long _do_fork(unsigned long, unsigned long, unsigned long, int __user *,
extern
long
do_fork
(
unsigned
long
,
unsigned
long
,
unsigned
long
,
int
__user
*
,
int
__user
*
);
extern
long
do_fork
(
unsigned
long
,
unsigned
long
,
unsigned
long
,
int
__user
*
,
int
__user
*
);
struct
task_struct
*
fork_idle
(
int
);
struct
task_struct
*
fork_idle
(
int
);
extern
pid_t
kernel_thread
(
int
(
*
fn
)(
void
*
),
void
*
arg
,
unsigned
long
flags
);
extern
pid_t
kernel_thread
(
int
(
*
fn
)(
void
*
),
void
*
arg
,
unsigned
long
flags
);
extern
long
kernel_wait4
(
pid_t
,
int
*
,
int
,
struct
rusage
*
);
extern
void
free_task
(
struct
task_struct
*
tsk
);
extern
void
free_task
(
struct
task_struct
*
tsk
);
...
...
kernel/compat.c
浏览文件 @
33dd955d
...
@@ -543,72 +543,6 @@ int put_compat_rusage(const struct rusage *r, struct compat_rusage __user *ru)
...
@@ -543,72 +543,6 @@ int put_compat_rusage(const struct rusage *r, struct compat_rusage __user *ru)
return
0
;
return
0
;
}
}
COMPAT_SYSCALL_DEFINE4
(
wait4
,
compat_pid_t
,
pid
,
compat_uint_t
__user
*
,
stat_addr
,
int
,
options
,
struct
compat_rusage
__user
*
,
ru
)
{
if
(
!
ru
)
{
return
sys_wait4
(
pid
,
stat_addr
,
options
,
NULL
);
}
else
{
struct
rusage
r
;
int
ret
;
unsigned
int
status
;
mm_segment_t
old_fs
=
get_fs
();
set_fs
(
KERNEL_DS
);
ret
=
sys_wait4
(
pid
,
(
stat_addr
?
(
unsigned
int
__user
*
)
&
status
:
NULL
),
options
,
(
struct
rusage
__user
*
)
&
r
);
set_fs
(
old_fs
);
if
(
ret
>
0
)
{
if
(
put_compat_rusage
(
&
r
,
ru
))
return
-
EFAULT
;
if
(
stat_addr
&&
put_user
(
status
,
stat_addr
))
return
-
EFAULT
;
}
return
ret
;
}
}
COMPAT_SYSCALL_DEFINE5
(
waitid
,
int
,
which
,
compat_pid_t
,
pid
,
struct
compat_siginfo
__user
*
,
uinfo
,
int
,
options
,
struct
compat_rusage
__user
*
,
uru
)
{
siginfo_t
info
;
struct
rusage
ru
;
long
ret
;
mm_segment_t
old_fs
=
get_fs
();
memset
(
&
info
,
0
,
sizeof
(
info
));
set_fs
(
KERNEL_DS
);
ret
=
sys_waitid
(
which
,
pid
,
(
siginfo_t
__user
*
)
&
info
,
options
,
uru
?
(
struct
rusage
__user
*
)
&
ru
:
NULL
);
set_fs
(
old_fs
);
if
((
ret
<
0
)
||
(
info
.
si_signo
==
0
))
return
ret
;
if
(
uru
)
{
/* sys_waitid() overwrites everything in ru */
if
(
COMPAT_USE_64BIT_TIME
)
ret
=
copy_to_user
(
uru
,
&
ru
,
sizeof
(
ru
));
else
ret
=
put_compat_rusage
(
&
ru
,
uru
);
if
(
ret
)
return
-
EFAULT
;
}
BUG_ON
(
info
.
si_code
&
__SI_MASK
);
info
.
si_code
|=
__SI_CHLD
;
return
copy_siginfo_to_user32
(
uinfo
,
&
info
);
}
static
int
compat_get_user_cpu_mask
(
compat_ulong_t
__user
*
user_mask_ptr
,
static
int
compat_get_user_cpu_mask
(
compat_ulong_t
__user
*
user_mask_ptr
,
unsigned
len
,
struct
cpumask
*
new_mask
)
unsigned
len
,
struct
cpumask
*
new_mask
)
{
{
...
...
kernel/exit.c
浏览文件 @
33dd955d
...
@@ -62,6 +62,7 @@
...
@@ -62,6 +62,7 @@
#include <linux/kcov.h>
#include <linux/kcov.h>
#include <linux/random.h>
#include <linux/random.h>
#include <linux/rcuwait.h>
#include <linux/rcuwait.h>
#include <linux/compat.h>
#include <linux/uaccess.h>
#include <linux/uaccess.h>
#include <asm/unistd.h>
#include <asm/unistd.h>
...
@@ -995,14 +996,21 @@ SYSCALL_DEFINE1(exit_group, int, error_code)
...
@@ -995,14 +996,21 @@ SYSCALL_DEFINE1(exit_group, int, error_code)
return
0
;
return
0
;
}
}
struct
waitid_info
{
pid_t
pid
;
uid_t
uid
;
int
status
;
int
cause
;
};
struct
wait_opts
{
struct
wait_opts
{
enum
pid_type
wo_type
;
enum
pid_type
wo_type
;
int
wo_flags
;
int
wo_flags
;
struct
pid
*
wo_pid
;
struct
pid
*
wo_pid
;
struct
siginfo
__user
*
wo_info
;
struct
waitid_info
*
wo_info
;
int
__user
*
wo_stat
;
int
wo_stat
;
struct
rusage
__user
*
wo_rusage
;
struct
rusage
*
wo_rusage
;
wait_queue_t
child_wait
;
wait_queue_t
child_wait
;
int
notask_error
;
int
notask_error
;
...
@@ -1049,34 +1057,6 @@ eligible_child(struct wait_opts *wo, bool ptrace, struct task_struct *p)
...
@@ -1049,34 +1057,6 @@ eligible_child(struct wait_opts *wo, bool ptrace, struct task_struct *p)
return
1
;
return
1
;
}
}
static
int
wait_noreap_copyout
(
struct
wait_opts
*
wo
,
struct
task_struct
*
p
,
pid_t
pid
,
uid_t
uid
,
int
why
,
int
status
)
{
struct
siginfo
__user
*
infop
;
int
retval
=
wo
->
wo_rusage
?
getrusage
(
p
,
RUSAGE_BOTH
,
wo
->
wo_rusage
)
:
0
;
put_task_struct
(
p
);
infop
=
wo
->
wo_info
;
if
(
infop
)
{
if
(
!
retval
)
retval
=
put_user
(
SIGCHLD
,
&
infop
->
si_signo
);
if
(
!
retval
)
retval
=
put_user
(
0
,
&
infop
->
si_errno
);
if
(
!
retval
)
retval
=
put_user
((
short
)
why
,
&
infop
->
si_code
);
if
(
!
retval
)
retval
=
put_user
(
pid
,
&
infop
->
si_pid
);
if
(
!
retval
)
retval
=
put_user
(
uid
,
&
infop
->
si_uid
);
if
(
!
retval
)
retval
=
put_user
(
status
,
&
infop
->
si_status
);
}
if
(
!
retval
)
retval
=
pid
;
return
retval
;
}
/*
/*
* Handle sys_wait4 work for one task in state EXIT_ZOMBIE. We hold
* Handle sys_wait4 work for one task in state EXIT_ZOMBIE. We hold
* read_lock(&tasklist_lock) on entry. If we return zero, we still hold
* read_lock(&tasklist_lock) on entry. If we return zero, we still hold
...
@@ -1085,30 +1065,23 @@ static int wait_noreap_copyout(struct wait_opts *wo, struct task_struct *p,
...
@@ -1085,30 +1065,23 @@ static int wait_noreap_copyout(struct wait_opts *wo, struct task_struct *p,
*/
*/
static
int
wait_task_zombie
(
struct
wait_opts
*
wo
,
struct
task_struct
*
p
)
static
int
wait_task_zombie
(
struct
wait_opts
*
wo
,
struct
task_struct
*
p
)
{
{
int
state
,
retval
,
status
;
int
state
,
status
;
pid_t
pid
=
task_pid_vnr
(
p
);
pid_t
pid
=
task_pid_vnr
(
p
);
uid_t
uid
=
from_kuid_munged
(
current_user_ns
(),
task_uid
(
p
));
uid_t
uid
=
from_kuid_munged
(
current_user_ns
(),
task_uid
(
p
));
struct
siginfo
__user
*
infop
;
struct
waitid_info
*
infop
;
if
(
!
likely
(
wo
->
wo_flags
&
WEXITED
))
if
(
!
likely
(
wo
->
wo_flags
&
WEXITED
))
return
0
;
return
0
;
if
(
unlikely
(
wo
->
wo_flags
&
WNOWAIT
))
{
if
(
unlikely
(
wo
->
wo_flags
&
WNOWAIT
))
{
int
exit_code
=
p
->
exit_code
;
status
=
p
->
exit_code
;
int
why
;
get_task_struct
(
p
);
get_task_struct
(
p
);
read_unlock
(
&
tasklist_lock
);
read_unlock
(
&
tasklist_lock
);
sched_annotate_sleep
();
sched_annotate_sleep
();
if
(
wo
->
wo_rusage
)
if
((
exit_code
&
0x7f
)
==
0
)
{
getrusage
(
p
,
RUSAGE_BOTH
,
wo
->
wo_rusage
);
why
=
CLD_EXITED
;
put_task_struct
(
p
);
status
=
exit_code
>>
8
;
goto
out_info
;
}
else
{
why
=
(
exit_code
&
0x80
)
?
CLD_DUMPED
:
CLD_KILLED
;
status
=
exit_code
&
0x7f
;
}
return
wait_noreap_copyout
(
wo
,
p
,
pid
,
uid
,
why
,
status
);
}
}
/*
/*
* Move the task's state to DEAD/TRACE, only one thread can do this.
* Move the task's state to DEAD/TRACE, only one thread can do this.
...
@@ -1181,38 +1154,11 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p)
...
@@ -1181,38 +1154,11 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p)
spin_unlock_irq
(
&
current
->
sighand
->
siglock
);
spin_unlock_irq
(
&
current
->
sighand
->
siglock
);
}
}
retval
=
wo
->
wo_rusage
if
(
wo
->
wo_rusage
)
?
getrusage
(
p
,
RUSAGE_BOTH
,
wo
->
wo_rusage
)
:
0
;
getrusage
(
p
,
RUSAGE_BOTH
,
wo
->
wo_rusage
)
;
status
=
(
p
->
signal
->
flags
&
SIGNAL_GROUP_EXIT
)
status
=
(
p
->
signal
->
flags
&
SIGNAL_GROUP_EXIT
)
?
p
->
signal
->
group_exit_code
:
p
->
exit_code
;
?
p
->
signal
->
group_exit_code
:
p
->
exit_code
;
if
(
!
retval
&&
wo
->
wo_stat
)
wo
->
wo_stat
=
status
;
retval
=
put_user
(
status
,
wo
->
wo_stat
);
infop
=
wo
->
wo_info
;
if
(
!
retval
&&
infop
)
retval
=
put_user
(
SIGCHLD
,
&
infop
->
si_signo
);
if
(
!
retval
&&
infop
)
retval
=
put_user
(
0
,
&
infop
->
si_errno
);
if
(
!
retval
&&
infop
)
{
int
why
;
if
((
status
&
0x7f
)
==
0
)
{
why
=
CLD_EXITED
;
status
>>=
8
;
}
else
{
why
=
(
status
&
0x80
)
?
CLD_DUMPED
:
CLD_KILLED
;
status
&=
0x7f
;
}
retval
=
put_user
((
short
)
why
,
&
infop
->
si_code
);
if
(
!
retval
)
retval
=
put_user
(
status
,
&
infop
->
si_status
);
}
if
(
!
retval
&&
infop
)
retval
=
put_user
(
pid
,
&
infop
->
si_pid
);
if
(
!
retval
&&
infop
)
retval
=
put_user
(
uid
,
&
infop
->
si_uid
);
if
(
!
retval
)
retval
=
pid
;
if
(
state
==
EXIT_TRACE
)
{
if
(
state
==
EXIT_TRACE
)
{
write_lock_irq
(
&
tasklist_lock
);
write_lock_irq
(
&
tasklist_lock
);
...
@@ -1229,7 +1175,21 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p)
...
@@ -1229,7 +1175,21 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p)
if
(
state
==
EXIT_DEAD
)
if
(
state
==
EXIT_DEAD
)
release_task
(
p
);
release_task
(
p
);
return
retval
;
out_info:
infop
=
wo
->
wo_info
;
if
(
infop
)
{
if
((
status
&
0x7f
)
==
0
)
{
infop
->
cause
=
CLD_EXITED
;
infop
->
status
=
status
>>
8
;
}
else
{
infop
->
cause
=
(
status
&
0x80
)
?
CLD_DUMPED
:
CLD_KILLED
;
infop
->
status
=
status
&
0x7f
;
}
infop
->
pid
=
pid
;
infop
->
uid
=
uid
;
}
return
pid
;
}
}
static
int
*
task_stopped_code
(
struct
task_struct
*
p
,
bool
ptrace
)
static
int
*
task_stopped_code
(
struct
task_struct
*
p
,
bool
ptrace
)
...
@@ -1265,8 +1225,8 @@ static int *task_stopped_code(struct task_struct *p, bool ptrace)
...
@@ -1265,8 +1225,8 @@ static int *task_stopped_code(struct task_struct *p, bool ptrace)
static
int
wait_task_stopped
(
struct
wait_opts
*
wo
,
static
int
wait_task_stopped
(
struct
wait_opts
*
wo
,
int
ptrace
,
struct
task_struct
*
p
)
int
ptrace
,
struct
task_struct
*
p
)
{
{
struct
siginfo
__user
*
infop
;
struct
waitid_info
*
infop
;
int
retval
,
exit_code
,
*
p_code
,
why
;
int
exit_code
,
*
p_code
,
why
;
uid_t
uid
=
0
;
/* unneeded, required by compiler */
uid_t
uid
=
0
;
/* unneeded, required by compiler */
pid_t
pid
;
pid_t
pid
;
...
@@ -1311,34 +1271,21 @@ static int wait_task_stopped(struct wait_opts *wo,
...
@@ -1311,34 +1271,21 @@ static int wait_task_stopped(struct wait_opts *wo,
why
=
ptrace
?
CLD_TRAPPED
:
CLD_STOPPED
;
why
=
ptrace
?
CLD_TRAPPED
:
CLD_STOPPED
;
read_unlock
(
&
tasklist_lock
);
read_unlock
(
&
tasklist_lock
);
sched_annotate_sleep
();
sched_annotate_sleep
();
if
(
wo
->
wo_rusage
)
getrusage
(
p
,
RUSAGE_BOTH
,
wo
->
wo_rusage
);
put_task_struct
(
p
);
if
(
unlikely
(
wo
->
wo_flags
&
WNOWAIT
))
if
(
likely
(
!
(
wo
->
wo_flags
&
WNOWAIT
)))
return
wait_noreap_copyout
(
wo
,
p
,
pid
,
uid
,
why
,
exit_code
);
wo
->
wo_stat
=
(
exit_code
<<
8
)
|
0x7f
;
retval
=
wo
->
wo_rusage
?
getrusage
(
p
,
RUSAGE_BOTH
,
wo
->
wo_rusage
)
:
0
;
if
(
!
retval
&&
wo
->
wo_stat
)
retval
=
put_user
((
exit_code
<<
8
)
|
0x7f
,
wo
->
wo_stat
);
infop
=
wo
->
wo_info
;
infop
=
wo
->
wo_info
;
if
(
!
retval
&&
infop
)
if
(
infop
)
{
retval
=
put_user
(
SIGCHLD
,
&
infop
->
si_signo
);
infop
->
cause
=
why
;
if
(
!
retval
&&
infop
)
infop
->
status
=
exit_code
;
retval
=
put_user
(
0
,
&
infop
->
si_errno
);
infop
->
pid
=
pid
;
if
(
!
retval
&&
infop
)
infop
->
uid
=
uid
;
retval
=
put_user
((
short
)
why
,
&
infop
->
si_code
);
}
if
(
!
retval
&&
infop
)
return
pid
;
retval
=
put_user
(
exit_code
,
&
infop
->
si_status
);
if
(
!
retval
&&
infop
)
retval
=
put_user
(
pid
,
&
infop
->
si_pid
);
if
(
!
retval
&&
infop
)
retval
=
put_user
(
uid
,
&
infop
->
si_uid
);
if
(
!
retval
)
retval
=
pid
;
put_task_struct
(
p
);
BUG_ON
(
!
retval
);
return
retval
;
}
}
/*
/*
...
@@ -1349,7 +1296,7 @@ static int wait_task_stopped(struct wait_opts *wo,
...
@@ -1349,7 +1296,7 @@ static int wait_task_stopped(struct wait_opts *wo,
*/
*/
static
int
wait_task_continued
(
struct
wait_opts
*
wo
,
struct
task_struct
*
p
)
static
int
wait_task_continued
(
struct
wait_opts
*
wo
,
struct
task_struct
*
p
)
{
{
int
retval
;
struct
waitid_info
*
infop
;
pid_t
pid
;
pid_t
pid
;
uid_t
uid
;
uid_t
uid
;
...
@@ -1374,22 +1321,20 @@ static int wait_task_continued(struct wait_opts *wo, struct task_struct *p)
...
@@ -1374,22 +1321,20 @@ static int wait_task_continued(struct wait_opts *wo, struct task_struct *p)
get_task_struct
(
p
);
get_task_struct
(
p
);
read_unlock
(
&
tasklist_lock
);
read_unlock
(
&
tasklist_lock
);
sched_annotate_sleep
();
sched_annotate_sleep
();
if
(
wo
->
wo_rusage
)
getrusage
(
p
,
RUSAGE_BOTH
,
wo
->
wo_rusage
);
put_task_struct
(
p
);
if
(
!
wo
->
wo_info
)
{
infop
=
wo
->
wo_info
;
retval
=
wo
->
wo_rusage
if
(
!
infop
)
{
?
getrusage
(
p
,
RUSAGE_BOTH
,
wo
->
wo_rusage
)
:
0
;
wo
->
wo_stat
=
0xffff
;
put_task_struct
(
p
);
if
(
!
retval
&&
wo
->
wo_stat
)
retval
=
put_user
(
0xffff
,
wo
->
wo_stat
);
if
(
!
retval
)
retval
=
pid
;
}
else
{
}
else
{
retval
=
wait_noreap_copyout
(
wo
,
p
,
pid
,
uid
,
infop
->
cause
=
CLD_CONTINUED
;
CLD_CONTINUED
,
SIGCONT
);
infop
->
pid
=
pid
;
BUG_ON
(
retval
==
0
);
infop
->
uid
=
uid
;
infop
->
status
=
SIGCONT
;
}
}
return
pid
;
return
retval
;
}
}
/*
/*
...
@@ -1617,8 +1562,8 @@ static long do_wait(struct wait_opts *wo)
...
@@ -1617,8 +1562,8 @@ static long do_wait(struct wait_opts *wo)
return
retval
;
return
retval
;
}
}
SYSCALL_DEFINE5
(
waitid
,
int
,
which
,
pid_t
,
upid
,
struct
siginfo
__user
*
,
static
long
kernel_waitid
(
int
which
,
pid_t
upid
,
struct
waitid_info
*
infop
,
infop
,
int
,
options
,
struct
rusage
__user
*
,
ru
)
int
options
,
struct
rusage
*
ru
)
{
{
struct
wait_opts
wo
;
struct
wait_opts
wo
;
struct
pid
*
pid
=
NULL
;
struct
pid
*
pid
=
NULL
;
...
@@ -1656,38 +1601,46 @@ SYSCALL_DEFINE5(waitid, int, which, pid_t, upid, struct siginfo __user *,
...
@@ -1656,38 +1601,46 @@ SYSCALL_DEFINE5(waitid, int, which, pid_t, upid, struct siginfo __user *,
wo
.
wo_pid
=
pid
;
wo
.
wo_pid
=
pid
;
wo
.
wo_flags
=
options
;
wo
.
wo_flags
=
options
;
wo
.
wo_info
=
infop
;
wo
.
wo_info
=
infop
;
wo
.
wo_stat
=
NULL
;
wo
.
wo_rusage
=
ru
;
wo
.
wo_rusage
=
ru
;
ret
=
do_wait
(
&
wo
);
ret
=
do_wait
(
&
wo
);
if
(
ret
>
0
)
{
if
(
ret
>
0
)
ret
=
0
;
ret
=
0
;
}
else
if
(
infop
)
{
/*
* For a WNOHANG return, clear out all the fields
* we would set so the user can easily tell the
* difference.
*/
if
(
!
ret
)
ret
=
put_user
(
0
,
&
infop
->
si_signo
);
if
(
!
ret
)
ret
=
put_user
(
0
,
&
infop
->
si_errno
);
if
(
!
ret
)
ret
=
put_user
(
0
,
&
infop
->
si_code
);
if
(
!
ret
)
ret
=
put_user
(
0
,
&
infop
->
si_pid
);
if
(
!
ret
)
ret
=
put_user
(
0
,
&
infop
->
si_uid
);
if
(
!
ret
)
ret
=
put_user
(
0
,
&
infop
->
si_status
);
}
put_pid
(
pid
);
put_pid
(
pid
);
return
ret
;
return
ret
;
}
}
SYSCALL_DEFINE4
(
wait4
,
pid_t
,
upid
,
int
__user
*
,
stat_addr
,
SYSCALL_DEFINE5
(
waitid
,
int
,
which
,
pid_t
,
upid
,
struct
siginfo
__user
*
,
int
,
options
,
struct
rusage
__user
*
,
ru
)
infop
,
int
,
options
,
struct
rusage
__user
*
,
ru
)
{
struct
rusage
r
;
struct
waitid_info
info
=
{.
status
=
0
};
long
err
=
kernel_waitid
(
which
,
upid
,
&
info
,
options
,
ru
?
&
r
:
NULL
);
if
(
!
err
)
{
if
(
ru
&&
copy_to_user
(
ru
,
&
r
,
sizeof
(
struct
rusage
)))
return
-
EFAULT
;
}
if
(
!
infop
)
return
err
;
user_access_begin
();
unsafe_put_user
(
err
?
0
:
SIGCHLD
,
&
infop
->
si_signo
,
Efault
);
unsafe_put_user
(
0
,
&
infop
->
si_errno
,
Efault
);
unsafe_put_user
((
short
)
info
.
cause
,
&
infop
->
si_code
,
Efault
);
unsafe_put_user
(
info
.
pid
,
&
infop
->
si_pid
,
Efault
);
unsafe_put_user
(
info
.
uid
,
&
infop
->
si_uid
,
Efault
);
unsafe_put_user
(
info
.
status
,
&
infop
->
si_status
,
Efault
);
user_access_end
();
return
err
;
Efault:
user_access_end
();
return
-
EFAULT
;
}
long
kernel_wait4
(
pid_t
upid
,
int
__user
*
stat_addr
,
int
options
,
struct
rusage
*
ru
)
{
{
struct
wait_opts
wo
;
struct
wait_opts
wo
;
struct
pid
*
pid
=
NULL
;
struct
pid
*
pid
=
NULL
;
...
@@ -1715,14 +1668,29 @@ SYSCALL_DEFINE4(wait4, pid_t, upid, int __user *, stat_addr,
...
@@ -1715,14 +1668,29 @@ SYSCALL_DEFINE4(wait4, pid_t, upid, int __user *, stat_addr,
wo
.
wo_pid
=
pid
;
wo
.
wo_pid
=
pid
;
wo
.
wo_flags
=
options
|
WEXITED
;
wo
.
wo_flags
=
options
|
WEXITED
;
wo
.
wo_info
=
NULL
;
wo
.
wo_info
=
NULL
;
wo
.
wo_stat
=
stat_addr
;
wo
.
wo_stat
=
0
;
wo
.
wo_rusage
=
ru
;
wo
.
wo_rusage
=
ru
;
ret
=
do_wait
(
&
wo
);
ret
=
do_wait
(
&
wo
);
put_pid
(
pid
);
put_pid
(
pid
);
if
(
ret
>
0
&&
stat_addr
&&
put_user
(
wo
.
wo_stat
,
stat_addr
))
ret
=
-
EFAULT
;
return
ret
;
return
ret
;
}
}
SYSCALL_DEFINE4
(
wait4
,
pid_t
,
upid
,
int
__user
*
,
stat_addr
,
int
,
options
,
struct
rusage
__user
*
,
ru
)
{
struct
rusage
r
;
long
err
=
kernel_wait4
(
upid
,
stat_addr
,
options
,
ru
?
&
r
:
NULL
);
if
(
err
>
0
)
{
if
(
ru
&&
copy_to_user
(
ru
,
&
r
,
sizeof
(
struct
rusage
)))
return
-
EFAULT
;
}
return
err
;
}
#ifdef __ARCH_WANT_SYS_WAITPID
#ifdef __ARCH_WANT_SYS_WAITPID
/*
/*
...
@@ -1735,3 +1703,56 @@ SYSCALL_DEFINE3(waitpid, pid_t, pid, int __user *, stat_addr, int, options)
...
@@ -1735,3 +1703,56 @@ SYSCALL_DEFINE3(waitpid, pid_t, pid, int __user *, stat_addr, int, options)
}
}
#endif
#endif
#ifdef CONFIG_COMPAT
COMPAT_SYSCALL_DEFINE4
(
wait4
,
compat_pid_t
,
pid
,
compat_uint_t
__user
*
,
stat_addr
,
int
,
options
,
struct
compat_rusage
__user
*
,
ru
)
{
struct
rusage
r
;
long
err
=
kernel_wait4
(
pid
,
stat_addr
,
options
,
ru
?
&
r
:
NULL
);
if
(
err
>
0
)
{
if
(
ru
&&
put_compat_rusage
(
&
r
,
ru
))
return
-
EFAULT
;
}
return
err
;
}
COMPAT_SYSCALL_DEFINE5
(
waitid
,
int
,
which
,
compat_pid_t
,
pid
,
struct
compat_siginfo
__user
*
,
infop
,
int
,
options
,
struct
compat_rusage
__user
*
,
uru
)
{
struct
rusage
ru
;
struct
waitid_info
info
=
{.
status
=
0
};
long
err
=
kernel_waitid
(
which
,
pid
,
&
info
,
options
,
uru
?
&
ru
:
NULL
);
if
(
!
err
&&
uru
)
{
/* kernel_waitid() overwrites everything in ru */
if
(
COMPAT_USE_64BIT_TIME
)
err
=
copy_to_user
(
uru
,
&
ru
,
sizeof
(
ru
));
else
err
=
put_compat_rusage
(
&
ru
,
uru
);
if
(
err
)
return
-
EFAULT
;
}
if
(
!
infop
)
return
err
;
user_access_begin
();
unsafe_put_user
(
err
?
0
:
SIGCHLD
,
&
infop
->
si_signo
,
Efault
);
unsafe_put_user
(
0
,
&
infop
->
si_errno
,
Efault
);
unsafe_put_user
((
short
)
info
.
cause
,
&
infop
->
si_code
,
Efault
);
unsafe_put_user
(
info
.
pid
,
&
infop
->
si_pid
,
Efault
);
unsafe_put_user
(
info
.
uid
,
&
infop
->
si_uid
,
Efault
);
unsafe_put_user
(
info
.
status
,
&
infop
->
si_status
,
Efault
);
user_access_end
();
return
err
;
Efault:
user_access_end
();
return
-
EFAULT
;
}
#endif
kernel/sys.c
浏览文件 @
33dd955d
...
@@ -1552,7 +1552,7 @@ static void accumulate_thread_rusage(struct task_struct *t, struct rusage *r)
...
@@ -1552,7 +1552,7 @@ static void accumulate_thread_rusage(struct task_struct *t, struct rusage *r)
r
->
ru_oublock
+=
task_io_get_oublock
(
t
);
r
->
ru_oublock
+=
task_io_get_oublock
(
t
);
}
}
static
void
k_
getrusage
(
struct
task_struct
*
p
,
int
who
,
struct
rusage
*
r
)
void
getrusage
(
struct
task_struct
*
p
,
int
who
,
struct
rusage
*
r
)
{
{
struct
task_struct
*
t
;
struct
task_struct
*
t
;
unsigned
long
flags
;
unsigned
long
flags
;
...
@@ -1626,20 +1626,16 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
...
@@ -1626,20 +1626,16 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
r
->
ru_maxrss
=
maxrss
*
(
PAGE_SIZE
/
1024
);
/* convert pages to KBs */
r
->
ru_maxrss
=
maxrss
*
(
PAGE_SIZE
/
1024
);
/* convert pages to KBs */
}
}
int
getrusage
(
struct
task_struct
*
p
,
int
who
,
struct
rusage
__user
*
ru
)
SYSCALL_DEFINE2
(
getrusage
,
int
,
who
,
struct
rusage
__user
*
,
ru
)
{
{
struct
rusage
r
;
struct
rusage
r
;
k_getrusage
(
p
,
who
,
&
r
);
return
copy_to_user
(
ru
,
&
r
,
sizeof
(
r
))
?
-
EFAULT
:
0
;
}
SYSCALL_DEFINE2
(
getrusage
,
int
,
who
,
struct
rusage
__user
*
,
ru
)
{
if
(
who
!=
RUSAGE_SELF
&&
who
!=
RUSAGE_CHILDREN
&&
if
(
who
!=
RUSAGE_SELF
&&
who
!=
RUSAGE_CHILDREN
&&
who
!=
RUSAGE_THREAD
)
who
!=
RUSAGE_THREAD
)
return
-
EINVAL
;
return
-
EINVAL
;
return
getrusage
(
current
,
who
,
ru
);
getrusage
(
current
,
who
,
&
r
);
return
copy_to_user
(
ru
,
&
r
,
sizeof
(
r
))
?
-
EFAULT
:
0
;
}
}
#ifdef CONFIG_COMPAT
#ifdef CONFIG_COMPAT
...
@@ -1651,7 +1647,7 @@ COMPAT_SYSCALL_DEFINE2(getrusage, int, who, struct compat_rusage __user *, ru)
...
@@ -1651,7 +1647,7 @@ COMPAT_SYSCALL_DEFINE2(getrusage, int, who, struct compat_rusage __user *, ru)
who
!=
RUSAGE_THREAD
)
who
!=
RUSAGE_THREAD
)
return
-
EINVAL
;
return
-
EINVAL
;
k_
getrusage
(
current
,
who
,
&
r
);
getrusage
(
current
,
who
,
&
r
);
return
put_compat_rusage
(
&
r
,
ru
);
return
put_compat_rusage
(
&
r
,
ru
);
}
}
#endif
#endif
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录