1 /*                               BSD License */
2 
3 /*         Redistribution and use in source and binary forms, with or */
4 /*         without modification, are permitted provided that the following */
5 /*         conditions are met: */
6 
7 
8 /*         Redistributions of source code must retain the above */
9 /*         copyright notice, this list of conditions and the following */
10 /*         disclaimer. */
11 
12 /*         Redistributions in binary form must reproduce the above */
13 /*         copyright notice, this list of conditions and the following */
14 /*         disclaimer in the documentation and/or other materials */
15 /*         provided with the distribution. */
16 
17 
18 /*       THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY */
19 /*       EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, */
20 /*       THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A */
21 /*       PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR */
22 /*       BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, */
23 /*       EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */
24 /*       TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */
25 /*       DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND */
26 /*       ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT */
27 /*       LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING */
28 /*       IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF */
29 /*       THE POSSIBILITY OF SUCH DAMAGE. */
30 
31 #include <stdlib.h>
32 #include <stdio.h>
33 #include <sched.h>
34 #include <errno.h>
35 #include <sys/types.h>
36 #ifdef HAVE_LIMITS_H
37 #include <limits.h>
38 #else
39 #define _POSIX_PATH_MAX 255
40 #endif
41 #include <string.h>
42 #include "util.h"
43 #include "isnumber.h"
44 #include "config.h"
45 char progname[_POSIX_PATH_MAX];
46 
47 void
print_usage()48 print_usage ()
49 {
50   fprintf (stderr, "Usage : %s [-h] [-v] -r|-o|-f pid [priority]\n\
51 Sets a new scheduler and/or priority for process identified with pid.\n\
52 Options:	-v be verbose.\n\
53 		-h print help (this text).\n\
54 		-r|-o|-f which scheduler to set.\n\n\
55 		Schedulers are:\n\
56 		-r Round Robin scheduler.\n\
57 		-f FIFO scheduler.\n\
58 		-o Other(normal) scheduler.\n\
59 		\n\
60 		pid - which pid to reschedule.\n\
61 		priority - new priority to set.\n", progname);
62 
63 }
64 
65 int
main(int argc,char * argv[])66 main (int argc, char *argv[])
67 {
68   pid_t thepid;
69   int newpri;
70   int ret;
71   struct sched_param pri, oldpri;
72   int oldsched, newsched = -1;
73   int verbose = 0;
74 
75   char *s;
76   strcpy (progname, argv[0]);
77   if (argc < 2)
78     {
79       print_usage ();
80       return EXIT_FAILURE;
81     }
82   while (--argc > 0 && (*++argv)[0] == '-')
83     {
84       for (s = argv[0] + 1; *s != '\0'; s++)
85 	{
86 	  switch (*s)
87 	    {
88 	    case 'h':
89 	      print_usage ();
90 	      return EXIT_FAILURE;
91 	      break;
92 	    case 'v':
93 	      verbose = 1;
94 	      break;
95 	    case 'r':
96 	      newsched = SCHED_RR;
97 	      break;
98 	    case 'f':
99 	      newsched = SCHED_FIFO;
100 	      break;
101 	    case 'o':
102 	      newsched = SCHED_OTHER;
103 	      break;
104 	    default:
105 	      fprintf (stderr,"Unrecognized option: %s\n", s);
106 	      print_usage ();
107 	      return EXIT_FAILURE;
108 
109 	    }
110 	}
111     }
112   if (newsched < 0)
113     {
114       fprintf(stderr,"Which scheduler?\n");
115       print_usage ();
116       return EXIT_FAILURE;
117     }
118   if (argc--)
119     {
120       thepid = (pid_t) atoi (argv[0]);
121     }
122   else
123     {
124       fprintf (stderr,"Failed: pid not specified\n");
125       print_usage ();
126       return EXIT_FAILURE;
127     }
128   ret = sched_getparam (thepid, &oldpri);
129   if (ret < 0)
130     {
131       perror ("Failed ");
132       return EXIT_FAILURE;
133     }
134   newpri = oldpri.sched_priority;
135   if (argc)
136     {
137       if (isnumber (*++argv))
138 	{
139 	  newpri = atoi (*argv);
140 
141 	}
142       else
143 	{
144 	  fprintf (stderr,"Failed: priority is not a number.\n");
145 	  return EXIT_FAILURE;
146 	}
147     }
148   if ((newpri > sched_get_priority_max (newsched)) || (newpri <
149 						       sched_get_priority_min
150 						       (newsched)))
151     {
152       fprintf (stderr,
153 	       "Priority %d is illegal, must be in range %d-%d for this scheduler.\n",
154 	       newpri, sched_get_priority_min (newsched),
155 	       sched_get_priority_max (newsched));
156       return EXIT_FAILURE;
157     }
158 
159   ret = oldsched = sched_getscheduler (thepid);
160   if (ret < 0)
161     {
162       perror ("Failed ");
163       return EXIT_FAILURE;
164     }
165   if (verbose)
166     {
167       printf ("Before: ");
168       print_sched (thepid, oldsched, &oldpri);
169     }
170   pri.sched_priority = newpri;
171   ret = sched_setscheduler (thepid, newsched, &pri);
172   if (ret < 0)
173     {
174       perror ("Failed ");
175       return EXIT_FAILURE;
176     }
177 
178   if (verbose)
179     {
180       printf ("After : ");
181       print_sched (thepid, newsched, &pri);
182     }
183   return EXIT_SUCCESS;
184 
185 
186 }
187