1/*
2 *  This program is free software; you can redistribute it and/or modify
3 *  it under the terms of the GNU General Public License version 2.
4 *
5 *  This program is distributed in the hope that it will be useful,
6 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
7 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8 *  GNU General Public License for more details.
9 *
10 *
11 * Test that sched_setparam() sets the scheduling parameters to the parameters
12 * specified in the sched_param structure pointed to by param.
13 */
14
15#include <sched.h>
16#include <stdio.h>
17#include <signal.h>
18#include <errno.h>
19#include <unistd.h>
20#include <stdlib.h>
21#include "posixtest.h"
22
23
24void child_proc(){
25	sigset_t sigset;
26	int sig;
27
28	if(sigemptyset(&sigset) != 0) {
29		perror("An error occurs when calling sigemptyset()");
30		exit(1);
31	}
32	if(sigaddset(&sigset,SIGUSR1) != 0) {
33		perror("An error occurs when calling sigaddset()");
34		exit(1);
35	}
36	if(sigwait(&sigset, &sig) != 0) {
37		perror("An error occurs when calling sigwait()");
38		exit(1);
39	}
40
41	exit(0);
42}
43
44
45int main(){
46        int result, child_pid, tmp_errno, policy;
47	int min_priority, new_priority, old_priority;
48	struct sched_param param;
49
50        /* Create a child process which wait SIGUSR1 */
51        child_pid = fork();
52        if(child_pid == -1){
53		perror("An error occurs when calling fork()");
54		return PTS_UNRESOLVED;
55        } else if (child_pid == 0){
56		child_proc();
57        }
58
59	if(sched_getparam(child_pid, &param) != 0){
60		perror("An error occurs when calling sched_getparam()");
61		kill(child_pid, SIGUSR1);
62		return PTS_UNRESOLVED;
63	}
64
65	/* Assume that the process have permission to change priority of
66	   its child */
67	old_priority = param.sched_priority;
68
69	policy = sched_getscheduler(0);
70	if(policy == -1) {
71		perror("An error occurs when calling sched_getscheduler()");
72		return PTS_UNRESOLVED;
73	}
74	min_priority = sched_get_priority_min(policy);
75
76	new_priority = param.sched_priority == min_priority ?
77		(param.sched_priority = sched_get_priority_max(policy)) :
78		(param.sched_priority = min_priority);
79
80
81	result = sched_setparam(child_pid, &param);
82	tmp_errno = errno;
83
84	if(sched_getparam(child_pid, &param) != 0){
85		perror("An error occurs when calling sched_getparam()");
86		kill(child_pid, SIGUSR1);
87		return PTS_UNRESOLVED;
88	}
89
90	if(result == 0 && param.sched_priority == new_priority) {
91		printf("Test PASSED\n");
92		kill(child_pid, SIGUSR1);
93		return PTS_PASS;
94	} else if(result == 0 && param.sched_priority == old_priority) {
95		printf("The param does not change.\n");
96		kill(child_pid, SIGUSR1);
97		return PTS_FAIL;
98	} else if(result == -1 && tmp_errno == EPERM) {
99		printf("The process have not permission to change the param of its child.\n");
100		kill(child_pid, SIGUSR1);
101		return PTS_UNRESOLVED;
102	} else if(result == -1 && tmp_errno == EINVAL) {
103		/* the new priority may be to big */
104		/* test with a new priority lower than the old one */
105		param.sched_priority = (new_priority -= 2);
106		result = sched_setparam(child_pid, &param);
107
108		if(result == 0 && param.sched_priority == new_priority) {
109			printf("Test PASSED");
110			kill(child_pid, SIGUSR1);
111			return PTS_PASS;
112		}
113	}
114
115	perror("Unknow error");
116	kill(child_pid, SIGUSR1);
117	return PTS_FAIL;
118}
119