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 
child_proc()24 void 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 
main()45 int 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