]> git.ipfire.org Git - thirdparty/util-linux.git/blame - schedutils/chrt.c
misc: consolidate version printing and close_stdout()
[thirdparty/util-linux.git] / schedutils / chrt.c
CommitLineData
48d7b13a 1/*
a7560c06 2 * chrt.c - manipulate a task's real-time attributes
48d7b13a 3 *
a7560c06
BS
4 * 27-Apr-2002: initial version - Robert Love <rml@tech9.net>
5 * 04-May-2011: make it thread-aware - Davidlohr Bueso <dave@gnu.org>
48d7b13a
KZ
6 *
7 * This program is free software; you can redistribute it and/or modify
a7560c06 8 * it under the terms of the GNU General Public License, version 2, as
48d7b13a
KZ
9 * published by the Free Software Foundation
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
7cebf0bb
SK
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
48d7b13a
KZ
19 *
20 * Copyright (C) 2004 Robert Love
21 */
22
48d7b13a
KZ
23#include <stdio.h>
24#include <stdlib.h>
25#include <sched.h>
26#include <unistd.h>
27#include <getopt.h>
28#include <errno.h>
88b60f0b
KZ
29#include <sys/time.h>
30#include <sys/resource.h>
bd9d9f05 31
b6534e4f 32#include "c.h"
bd9d9f05 33#include "nls.h"
ed8ec2a6 34#include "closestream.h"
8abcf290 35#include "strutils.h"
78904e76 36#include "procutils.h"
24295096 37
09dd84ca
KZ
38/* the SCHED_BATCH is supported since Linux 2.6.16
39 * -- temporary workaround for people with old glibc headers
40 */
b64279da 41#if defined (__linux__) && !defined(SCHED_BATCH)
09dd84ca
KZ
42# define SCHED_BATCH 3
43#endif
44
c779d6e9
MS
45/* the SCHED_IDLE is supported since Linux 2.6.23
46 * commit id 0e6aca43e08a62a48d6770e9a159dbec167bf4c6
47 * -- temporary workaround for people with old glibc headers
48 */
b64279da 49#if defined (__linux__) && !defined(SCHED_IDLE)
c779d6e9
MS
50# define SCHED_IDLE 5
51#endif
52
acde3a05 53/* flag by sched_getscheduler() */
0fefbedc 54#if defined(__linux__) && !defined(SCHED_RESET_ON_FORK)
acde3a05
KZ
55# define SCHED_RESET_ON_FORK 0x40000000
56#endif
57
58/* flag by sched_getattr() */
59#if defined(__linux__) && !defined(SCHED_FLAG_RESET_ON_FORK)
60# define SCHED_FLAG_RESET_ON_FORK 0x01
0fefbedc
AK
61#endif
62
15167589
KZ
63#if defined (__linux__) && !defined(HAVE_SCHED_SETATTR)
64# include <sys/syscall.h>
65#endif
66
6f27e449
KZ
67/* usable kernel-headers, but old glibc-headers */
68#if defined (__linux__) && !defined(SYS_sched_setattr) && defined(__NR_sched_setattr)
69# define SYS_sched_setattr __NR_sched_setattr
70#endif
71
72#if defined (__linux__) && !defined(SYS_sched_getattr) && defined(__NR_sched_getattr)
73# define SYS_sched_getattr __NR_sched_getattr
74#endif
75
15167589
KZ
76#if defined (__linux__) && !defined(HAVE_SCHED_SETATTR) && defined(SYS_sched_setattr)
77# define HAVE_SCHED_SETATTR
78
79struct sched_attr {
80 uint32_t size;
81 uint32_t sched_policy;
82 uint64_t sched_flags;
83
84 /* SCHED_NORMAL, SCHED_BATCH */
85 int32_t sched_nice;
86
87 /* SCHED_FIFO, SCHED_RR */
88 uint32_t sched_priority;
89
90 /* SCHED_DEADLINE (nsec) */
91 uint64_t sched_runtime;
92 uint64_t sched_deadline;
93 uint64_t sched_period;
94};
95
96static int sched_setattr(pid_t pid, const struct sched_attr *attr, unsigned int flags)
97{
98 return syscall(SYS_sched_setattr, pid, attr, flags);
99}
100
101static int sched_getattr(pid_t pid, struct sched_attr *attr, unsigned int size, unsigned int flags)
102{
103 return syscall(SYS_sched_getattr, pid, attr, size, flags);
104}
1a7e6395
KZ
105#endif
106
107/* the SCHED_DEADLINE is supported since Linux 3.14
108 * commit id aab03e05e8f7e26f51dee792beddcb5cca9215a5
109 * -- sched_setattr() is required for this policy!
110 */
111#if defined (__linux__) && !defined(SCHED_DEADLINE) && defined(HAVE_SCHED_SETATTR)
112# define SCHED_DEADLINE 6
113#endif
15167589 114
7a4ea566
KZ
115/* control struct */
116struct chrt_ctl {
117 pid_t pid;
118 int policy; /* SCHED_* */
119 int priority;
120
1a7e6395
KZ
121 uint64_t runtime; /* --sched-* options */
122 uint64_t deadline;
123 uint64_t period;
124
7a4ea566
KZ
125 unsigned int all_tasks : 1, /* all threads of the PID */
126 reset_on_fork : 1, /* SCHED_RESET_ON_FORK */
a30cf650 127 altered : 1, /* sched_set**() used */
7a4ea566
KZ
128 verbose : 1; /* verbose output */
129};
0fefbedc 130
5118d1be 131static void __attribute__((__noreturn__)) usage(void)
48d7b13a 132{
5118d1be 133 FILE *out = stdout;
aaf6349f 134
451dbcfa 135 fputs(_("Show or change the real-time scheduling attributes of a process.\n"), out);
9acbe2aa
BS
136 fputs(USAGE_SEPARATOR, out);
137 fputs(_("Set policy:\n"
138 " chrt [options] <priority> <command> [<arg>...]\n"
a6fec537 139 " chrt [options] --pid <priority> <pid>\n"), out);
9acbe2aa
BS
140 fputs(USAGE_SEPARATOR, out);
141 fputs(_("Get policy:\n"
142 " chrt [options] -p <pid>\n"), out);
aaf6349f 143
9acbe2aa
BS
144 fputs(USAGE_SEPARATOR, out);
145 fputs(_("Policy options:\n"), out);
146 fputs(_(" -b, --batch set policy to SCHED_BATCH\n"), out);
1a7e6395 147 fputs(_(" -d, --deadline set policy to SCHED_DEADLINE\n"), out);
9acbe2aa
BS
148 fputs(_(" -f, --fifo set policy to SCHED_FIFO\n"), out);
149 fputs(_(" -i, --idle set policy to SCHED_IDLE\n"), out);
150 fputs(_(" -o, --other set policy to SCHED_OTHER\n"), out);
151 fputs(_(" -r, --rr set policy to SCHED_RR (default)\n"), out);
aaf6349f 152
9acbe2aa 153 fputs(USAGE_SEPARATOR, out);
1a7e6395
KZ
154 fputs(_("Scheduling options:\n"), out);
155 fputs(_(" -R, --reset-on-fork set SCHED_RESET_ON_FORK for FIFO or RR\n"), out);
156 fputs(_(" -T, --sched-runtime <ns> runtime parameter for DEADLINE\n"), out);
157 fputs(_(" -P, --sched-period <ns> period parameter for DEADLINE\n"), out);
158 fputs(_(" -D, --sched-deadline <ns> deadline parameter for DEADLINE\n"), out);
159
9acbe2aa
BS
160 fputs(USAGE_SEPARATOR, out);
161 fputs(_("Other options:\n"), out);
162 fputs(_(" -a, --all-tasks operate on all the tasks (threads) for a given pid\n"), out);
163 fputs(_(" -m, --max show min and max valid priorities\n"), out);
164 fputs(_(" -p, --pid operate on existing given pid\n"), out);
165 fputs(_(" -v, --verbose display status information\n"), out);
166
167 fputs(USAGE_SEPARATOR, out);
f45f3ec3 168 printf(USAGE_HELP_OPTIONS(22));
bd9d9f05 169
f45f3ec3 170 printf(USAGE_MAN_TAIL("chrt(1)"));
5118d1be 171 exit(EXIT_SUCCESS);
48d7b13a
KZ
172}
173
acde3a05 174static const char *get_policy_name(int policy)
48d7b13a 175{
48d7b13a
KZ
176 switch (policy) {
177 case SCHED_OTHER:
acde3a05 178 return "SCHED_OTHER";
48d7b13a 179 case SCHED_FIFO:
a03eac52 180#ifdef SCHED_RESET_ON_FORK
110d680a 181 case SCHED_FIFO | SCHED_RESET_ON_FORK:
a03eac52 182#endif
acde3a05 183 return "SCHED_FIFO";
b64279da 184#ifdef SCHED_IDLE
c779d6e9 185 case SCHED_IDLE:
acde3a05 186 return "SCHED_IDLE";
b64279da 187#endif
48d7b13a 188 case SCHED_RR:
a03eac52 189#ifdef SCHED_RESET_ON_FORK
59e4a382 190 case SCHED_RR | SCHED_RESET_ON_FORK:
a03eac52 191#endif
acde3a05 192 return "SCHED_RR";
b64279da 193#ifdef SCHED_BATCH
df3773fb 194 case SCHED_BATCH:
acde3a05 195 return "SCHED_BATCH";
1a7e6395
KZ
196#endif
197#ifdef SCHED_DEADLINE
198 case SCHED_DEADLINE:
acde3a05 199 return "SCHED_DEADLINE";
b64279da 200#endif
48d7b13a 201 default:
acde3a05 202 break;
48d7b13a
KZ
203 }
204
acde3a05
KZ
205 return _("unknown");
206}
207
208static void show_sched_pid_info(struct chrt_ctl *ctl, pid_t pid)
209{
685f5449 210 int policy = -1, reset_on_fork = 0, prio = 0;
acde3a05
KZ
211#ifdef SCHED_DEADLINE
212 uint64_t deadline = 0, runtime = 0, period = 0;
213#endif
214
215 /* don't display "pid 0" as that is confusing */
216 if (!pid)
217 pid = getpid();
218
6f27e449
KZ
219 errno = 0;
220
221 /*
222 * New way
223 */
acde3a05
KZ
224#ifdef HAVE_SCHED_SETATTR
225 {
226 struct sched_attr sa;
227
6f27e449
KZ
228 if (sched_getattr(pid, &sa, sizeof(sa), 0) != 0) {
229 if (errno == ENOSYS)
230 goto fallback;
acde3a05 231 err(EXIT_FAILURE, _("failed to get pid %d's policy"), pid);
6f27e449 232 }
acde3a05
KZ
233
234 policy = sa.sched_policy;
235 prio = sa.sched_priority;
236 reset_on_fork = sa.sched_flags & SCHED_FLAG_RESET_ON_FORK;
237 deadline = sa.sched_deadline;
238 runtime = sa.sched_runtime;
239 period = sa.sched_period;
240 }
6f27e449
KZ
241
242 /*
243 * Old way
244 */
245fallback:
fded05ac
RM
246 if (errno == ENOSYS)
247#endif
248 {
acde3a05
KZ
249 struct sched_param sp;
250
251 policy = sched_getscheduler(pid);
252 if (policy == -1)
253 err(EXIT_FAILURE, _("failed to get pid %d's policy"), pid);
254
255 if (sched_getparam(pid, &sp) != 0)
256 err(EXIT_FAILURE, _("failed to get pid %d's attributes"), pid);
257 else
258 prio = sp.sched_priority;
259# ifdef SCHED_RESET_ON_FORK
260 if (policy == (SCHED_FIFO|SCHED_RESET_ON_FORK) || policy == (SCHED_BATCH|SCHED_RESET_ON_FORK))
261 reset_on_fork = 1;
262# endif
263 }
48d7b13a 264
a30cf650 265 if (ctl->altered)
acde3a05 266 printf(_("pid %d's new scheduling policy: %s"), pid, get_policy_name(policy));
a9a3e5f2 267 else
acde3a05
KZ
268 printf(_("pid %d's current scheduling policy: %s"), pid, get_policy_name(policy));
269
270 if (reset_on_fork)
271 printf("|SCHED_RESET_ON_FORK");
272 putchar('\n');
273
274 if (ctl->altered)
275 printf(_("pid %d's new scheduling priority: %d\n"), pid, prio);
276 else
277 printf(_("pid %d's current scheduling priority: %d\n"), pid, prio);
278
279#ifdef SCHED_DEADLINE
280 if (policy == SCHED_DEADLINE) {
281 if (ctl->altered)
282 printf(_("pid %d's new runtime/deadline/period parameters: %ju/%ju/%ju\n"),
283 pid, runtime, deadline, period);
284 else
285 printf(_("pid %d's current runtime/deadline/period parameters: %ju/%ju/%ju\n"),
286 pid, runtime, deadline, period);
287 }
288#endif
48d7b13a
KZ
289}
290
a30cf650
KZ
291
292static void show_sched_info(struct chrt_ctl *ctl)
293{
294 if (ctl->all_tasks) {
295 pid_t tid;
296 struct proc_tasks *ts = proc_open_tasks(ctl->pid);
297
298 if (!ts)
299 err(EXIT_FAILURE, _("cannot obtain the list of tasks"));
300
301 while (!proc_next_tid(ts, &tid))
302 show_sched_pid_info(ctl, tid);
303
304 proc_close_tasks(ts);
305 } else
306 show_sched_pid_info(ctl, ctl->pid);
307}
308
48d7b13a
KZ
309static void show_min_max(void)
310{
90b7d261 311 unsigned long i;
110d680a
SK
312 int policies[] = {
313 SCHED_OTHER,
314 SCHED_FIFO,
315 SCHED_RR,
b64279da 316#ifdef SCHED_BATCH
110d680a 317 SCHED_BATCH,
b64279da
AJ
318#endif
319#ifdef SCHED_IDLE
110d680a 320 SCHED_IDLE,
1a7e6395
KZ
321#endif
322#ifdef SCHED_DEADLINE
323 SCHED_DEADLINE,
b64279da 324#endif
110d680a 325 };
bd9d9f05
KZ
326
327 for (i = 0; i < ARRAY_SIZE(policies); i++) {
acde3a05
KZ
328 int plc = policies[i];
329 int max = sched_get_priority_max(plc);
330 int min = sched_get_priority_min(plc);
bd9d9f05
KZ
331
332 if (max >= 0 && min >= 0)
078720a7 333 printf(_("%s min/max priority\t: %d/%d\n"),
acde3a05 334 get_policy_name(plc), min, max);
bd9d9f05 335 else
078720a7 336 printf(_("%s not supported?\n"), get_policy_name(plc));
bd9d9f05 337 }
48d7b13a
KZ
338}
339
6f27e449 340static int set_sched_one_by_setscheduler(struct chrt_ctl *ctl, pid_t pid)
4820a737
KZ
341{
342 struct sched_param sp = { .sched_priority = ctl->priority };
15167589 343 int policy = ctl->policy;
4820a737 344
88b60f0b 345 errno = 0;
15167589
KZ
346# ifdef SCHED_RESET_ON_FORK
347 if (ctl->reset_on_fork)
348 policy |= SCHED_RESET_ON_FORK;
349# endif
350 return sched_setscheduler(pid, policy, &sp);
351}
352
6f27e449
KZ
353
354#ifndef HAVE_SCHED_SETATTR
355static int set_sched_one(struct chrt_ctl *ctl, pid_t pid)
356{
357 return set_sched_one_by_setscheduler(ctl, pid);
358}
359
15167589
KZ
360#else /* !HAVE_SCHED_SETATTR */
361static int set_sched_one(struct chrt_ctl *ctl, pid_t pid)
362{
88b60f0b
KZ
363 struct sched_attr sa = { .size = sizeof(struct sched_attr) };
364
365 /* old API is good enough for non-deadline */
366 if (ctl->policy != SCHED_DEADLINE)
367 return set_sched_one_by_setscheduler(ctl, pid);
368
369 /* no changeed by chrt, follow the current setting */
370 sa.sched_nice = getpriority(PRIO_PROCESS, pid);
371
1a7e6395 372 /* use main() to check if the setting makes sense */
88b60f0b
KZ
373 sa.sched_policy = ctl->policy;
374 sa.sched_priority = ctl->priority;
375 sa.sched_runtime = ctl->runtime;
376 sa.sched_period = ctl->period;
377 sa.sched_deadline = ctl->deadline;
6f27e449 378
15167589
KZ
379# ifdef SCHED_RESET_ON_FORK
380 if (ctl->reset_on_fork)
381 sa.sched_flags |= SCHED_RESET_ON_FORK;
382# endif
6f27e449 383 errno = 0;
88b60f0b 384 return sched_setattr(pid, &sa, 0);
15167589
KZ
385}
386#endif /* HAVE_SCHED_SETATTR */
387
388static void set_sched(struct chrt_ctl *ctl)
389{
4820a737
KZ
390 if (ctl->all_tasks) {
391 pid_t tid;
392 struct proc_tasks *ts = proc_open_tasks(ctl->pid);
393
394 if (!ts)
395 err(EXIT_FAILURE, _("cannot obtain the list of tasks"));
396
397 while (!proc_next_tid(ts, &tid))
15167589 398 if (set_sched_one(ctl, tid) == -1)
4820a737
KZ
399 err(EXIT_FAILURE, _("failed to set tid %d's policy"), tid);
400
401 proc_close_tasks(ts);
402
15167589 403 } else if (set_sched_one(ctl, ctl->pid) == -1)
4820a737
KZ
404 err(EXIT_FAILURE, _("failed to set pid %d's policy"), ctl->pid);
405
406 ctl->altered = 1;
407}
408
110d680a 409int main(int argc, char **argv)
48d7b13a 410{
c7adc2f2 411 struct chrt_ctl _ctl = { .pid = -1, .policy = SCHED_RR }, *ctl = &_ctl;
4820a737 412 int c;
48d7b13a 413
6c7d5ae9 414 static const struct option longopts[] = {
1a7e6395
KZ
415 { "all-tasks", no_argument, NULL, 'a' },
416 { "batch", no_argument, NULL, 'b' },
417 { "deadline", no_argument, NULL, 'd' },
418 { "fifo", no_argument, NULL, 'f' },
419 { "idle", no_argument, NULL, 'i' },
420 { "pid", no_argument, NULL, 'p' },
421 { "help", no_argument, NULL, 'h' },
422 { "max", no_argument, NULL, 'm' },
423 { "other", no_argument, NULL, 'o' },
424 { "rr", no_argument, NULL, 'r' },
425 { "sched-runtime", required_argument, NULL, 'T' },
426 { "sched-period", required_argument, NULL, 'P' },
427 { "sched-deadline", required_argument, NULL, 'D' },
428 { "reset-on-fork", no_argument, NULL, 'R' },
429 { "verbose", no_argument, NULL, 'v' },
430 { "version", no_argument, NULL, 'V' },
431 { NULL, no_argument, NULL, 0 }
48d7b13a
KZ
432 };
433
bd9d9f05
KZ
434 setlocale(LC_ALL, "");
435 bindtextdomain(PACKAGE, LOCALEDIR);
436 textdomain(PACKAGE);
2c308875 437 close_stdout_atexit();
bd9d9f05 438
b3a50671 439 while((c = getopt_long(argc, argv, "+abdD:fiphmoP:T:rRvV", longopts, NULL)) != -1)
48d7b13a 440 {
4820a737 441 switch (c) {
78904e76 442 case 'a':
7a4ea566 443 ctl->all_tasks = 1;
78904e76 444 break;
df3773fb 445 case 'b':
b64279da 446#ifdef SCHED_BATCH
7a4ea566 447 ctl->policy = SCHED_BATCH;
1a7e6395
KZ
448#endif
449 break;
450
451 case 'd':
452#ifdef SCHED_DEADLINE
453 ctl->policy = SCHED_DEADLINE;
b64279da 454#endif
df3773fb 455 break;
48d7b13a 456 case 'f':
7a4ea566 457 ctl->policy = SCHED_FIFO;
48d7b13a 458 break;
cdfb1e88 459 case 'R':
7a4ea566 460 ctl->reset_on_fork = 1;
c150589f 461 break;
c779d6e9 462 case 'i':
b64279da 463#ifdef SCHED_IDLE
7a4ea566 464 ctl->policy = SCHED_IDLE;
b64279da 465#endif
c779d6e9 466 break;
48d7b13a
KZ
467 case 'm':
468 show_min_max();
110d680a 469 return EXIT_SUCCESS;
48d7b13a 470 case 'o':
7a4ea566 471 ctl->policy = SCHED_OTHER;
48d7b13a
KZ
472 break;
473 case 'p':
474 errno = 0;
7a4ea566 475 ctl->pid = strtos32_or_err(argv[argc - 1], _("invalid PID argument"));
48d7b13a
KZ
476 break;
477 case 'r':
7a4ea566 478 ctl->policy = SCHED_RR;
48d7b13a
KZ
479 break;
480 case 'v':
7a4ea566 481 ctl->verbose = 1;
48d7b13a 482 break;
1a7e6395
KZ
483 case 'T':
484 ctl->runtime = strtou64_or_err(optarg, _("invalid runtime argument"));
485 break;
486 case 'P':
487 ctl->period = strtou64_or_err(optarg, _("invalid period argument"));
488 break;
489 case 'D':
490 ctl->deadline = strtou64_or_err(optarg, _("invalid deadline argument"));
491 break;
2c308875 492
48d7b13a 493 case 'V':
2c308875 494 print_version(EXIT_SUCCESS);
48d7b13a 495 case 'h':
5118d1be 496 usage();
48d7b13a 497 default:
677ec86c 498 errtryhelp(EXIT_FAILURE);
48d7b13a 499 }
48d7b13a
KZ
500 }
501
7a4ea566 502 if (((ctl->pid > -1) && argc - optind < 1) ||
5118d1be
RM
503 ((ctl->pid == -1) && argc - optind < 2)) {
504 warnx(_("bad usage"));
505 errtryhelp(EXIT_FAILURE);
506}
48d7b13a 507
7a4ea566 508 if ((ctl->pid > -1) && (ctl->verbose || argc - optind == 1)) {
a30cf650 509 show_sched_info(ctl);
48d7b13a 510 if (argc - optind == 1)
bd9d9f05 511 return EXIT_SUCCESS;
48d7b13a
KZ
512 }
513
514 errno = 0;
7a4ea566 515 ctl->priority = strtos32_or_err(argv[optind], _("invalid priority argument"));
48d7b13a 516
4951f9b3 517#ifdef SCHED_RESET_ON_FORK
1a7e6395
KZ
518 if (ctl->reset_on_fork && ctl->policy != SCHED_FIFO && ctl->policy != SCHED_RR)
519 errx(EXIT_FAILURE, _("--reset-on-fork option is supported for "
520 "SCHED_FIFO and SCHED_RR policies only"));
521#endif
522#ifdef SCHED_DEADLINE
523 if ((ctl->runtime || ctl->deadline || ctl->period) && ctl->policy != SCHED_DEADLINE)
524 errx(EXIT_FAILURE, _("--sched-{runtime,deadline,period} options "
525 "are supported for SCHED_DEADLINE only"));
526 if (ctl->policy == SCHED_DEADLINE) {
527 /* The basic rule is runtime <= deadline <= period, so we can
528 * make deadline and runtime optional on command line. Note we
529 * don't check any values or set any defaults, it's kernel
530 * responsibility.
531 */
532 if (ctl->deadline == 0)
533 ctl->deadline = ctl->period;
534 if (ctl->runtime == 0)
535 ctl->runtime = ctl->deadline;
536 }
537#else
538 if (ctl->runtime || ctl->deadline || ctl->period)
539 errx(EXIT_FAILURE, _("SCHED_DEADLINE is unsupported"));
4951f9b3 540#endif
7a4ea566
KZ
541 if (ctl->pid == -1)
542 ctl->pid = 0;
2e31d1c3
SK
543 if (ctl->priority < sched_get_priority_min(ctl->policy) ||
544 sched_get_priority_max(ctl->policy) < ctl->priority)
545 errx(EXIT_FAILURE,
546 _("unsupported priority value for the policy: %d: see --max for valid range"),
547 ctl->priority);
4820a737 548 set_sched(ctl);
a30cf650 549
7a4ea566 550 if (ctl->verbose)
a30cf650 551 show_sched_info(ctl);
48d7b13a 552
7a4ea566 553 if (!ctl->pid) {
48d7b13a
KZ
554 argv += optind + 1;
555 execvp(argv[0], argv);
61b62222 556 errexec(argv[0]);
48d7b13a
KZ
557 }
558
bd9d9f05 559 return EXIT_SUCCESS;
48d7b13a 560}