1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License").  You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22/*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
23/*	  All Rights Reserved  	*/
24
25
26/*
27 * Copyright 2000-2003 Sun Microsystems, Inc.  All rights reserved.
28 * Use is subject to license terms.
29 */
30
31#pragma ident	"%Z%%M%	%I%	%E% SMI"
32
33/*
34**	nice
35*/
36
37
38#include	<stdio.h>
39#include	<locale.h>
40#include	<stdlib.h>
41#include	<string.h>
42#include	<unistd.h>
43#include	<errno.h>
44
45
46static void usage(void);
47
48int
49main(int argc, char *argv[])
50{
51	long	nicarg = 10;
52
53	(void) setlocale(LC_ALL, "");
54#if !defined(TEXT_DOMAIN)
55#define	TEXT_DOMAIN	"SYS_TEST"
56#endif
57	(void) textdomain(TEXT_DOMAIN);
58
59
60	if (argc < 2)
61		usage();
62
63
64	if (argv[1][0] == '-') {
65		if (strcmp(argv[1], "--") == 0) {
66			argv++;
67			argc--;
68		} else {
69			register char	*p = argv[1];
70			char	*nicarg_str;
71			char 	*end_ptr;
72
73			if (*++p == 'n') {	/* -n55 new form, XCU4 */
74				/*
75				 * for situations like -n-10
76				 * else case assigns p instead of argv
77				 */
78				if (!(*++p)) {
79					/* Next arg is priority */
80					argv++;
81					argc--;
82					if (argc < 2)
83						usage();
84					nicarg_str = argv[1];
85				} else {
86					/* Priority embedded eg. -n-10 */
87					nicarg_str = p;
88				}
89			} else {	/* -55 obs form, XCU4 */
90				nicarg_str = &argv[1][1];
91			}
92			nicarg = strtol(nicarg_str, &end_ptr, 10);
93			if (*end_ptr) {
94				(void) fprintf(stderr,
95				gettext("nice: argument must be numeric.\n"));
96				usage();
97			}
98
99			if( --argc < 2 )
100				usage();
101
102			argv++;
103			if (strcmp(argv[1], "--") == 0) {
104				argv++;
105				argc--;
106			}
107		}
108	}
109
110	if (argc < 2)
111		usage();
112
113	errno = 0;
114	if (nice(nicarg) == -1) {
115		/*
116		 * Could be an error or a legitimate return value.
117		 * The only error we care about is EINVAL, which will
118		 * be returned by the scheduling class we are in if
119		 * nice is invalid for this class.
120		 * For any error other than EINVAL
121		 * we will go ahead and exec the command even though
122		 * the priority change failed.
123		 */
124		if (errno == EINVAL) {
125			(void) fprintf(stderr, gettext(
126			    "nice: invalid operation; "
127			    "scheduling class does not support nice\n"));
128			return (2);
129		}
130	}
131	(void) execvp(argv[1], &argv[1]);
132	(void) fprintf(stderr, gettext("%s: %s\n"), strerror(errno), argv[1]);
133	/*
134	 * POSIX.2 exit status:
135	 * 127 if utility is not found.
136	 * 126 if utility cannot be invoked.
137	 */
138	return (errno == ENOENT || errno == ENOTDIR ? 127 : 126);
139}
140
141static void
142usage()
143{
144	(void) fprintf(stderr,
145	gettext("nice: usage: nice [-n increment] utility [argument ...]\n"));
146	exit(2);
147}
148