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 (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 31 #pragma ident "%Z%%M% %I% %E% SMI" 32 33 /* 34 * ulimit builtin 35 */ 36 37 #include <sys/resource.h> 38 #include <stdlib.h> 39 #include "defs.h" 40 41 /* 42 * order is important in this table! it is indexed by resource ID. 43 */ 44 45 static struct rlimtab { 46 char *name; 47 char *scale; 48 rlim_t divisor; 49 } rlimtab[] = { 50 /* RLIMIT_CPU */ "time", "seconds", 1, 51 /* RLIMIT_FSIZE */ "file", "blocks", 512, 52 /* RLIMIT_DATA */ "data", "kbytes", 1024, 53 /* RLIMIT_STACK */ "stack", "kbytes", 1024, 54 /* RLIMIT_CORE */ "coredump", "blocks", 512, 55 /* RLIMIT_NOFILE */ "nofiles", "descriptors", 1, 56 /* RLIMIT_VMEM */ "memory", "kbytes", 1024, 57 }; 58 59 void 60 sysulimit(int argc, char **argv) 61 { 62 extern int opterr, optind; 63 int savopterr, savoptind, savsp; 64 char *savoptarg; 65 char *args; 66 char errargs[PATH_MAX]; 67 int hard, soft, cnt, c, res; 68 rlim_t limit, new_limit; 69 struct rlimit rlimit; 70 char resources[RLIM_NLIMITS]; 71 72 for (res = 0; res < RLIM_NLIMITS; res++) { 73 resources[res] = 0; 74 } 75 76 savoptind = optind; 77 savopterr = opterr; 78 savsp = _sp; 79 savoptarg = optarg; 80 optind = 1; 81 _sp = 1; 82 opterr = 0; 83 hard = 0; 84 soft = 0; 85 cnt = 0; 86 87 while ((c = getopt(argc, argv, "HSacdfnstv")) != -1) { 88 switch (c) { 89 case 'S': 90 soft++; 91 continue; 92 case 'H': 93 hard++; 94 continue; 95 case 'a': 96 for (res = 0; res < RLIM_NLIMITS; res++) { 97 resources[res]++; 98 } 99 cnt = RLIM_NLIMITS; 100 continue; 101 case 'c': 102 res = RLIMIT_CORE; 103 break; 104 case 'd': 105 res = RLIMIT_DATA; 106 break; 107 case 'f': 108 res = RLIMIT_FSIZE; 109 break; 110 case 'n': 111 res = RLIMIT_NOFILE; 112 break; 113 case 's': 114 res = RLIMIT_STACK; 115 break; 116 case 't': 117 res = RLIMIT_CPU; 118 break; 119 case 'v': 120 res = RLIMIT_VMEM; 121 break; 122 case '?': 123 gfailure(usage, ulimuse); 124 goto err; 125 } 126 resources[res]++; 127 cnt++; 128 } 129 130 if (cnt == 0) { 131 resources[res = RLIMIT_FSIZE]++; 132 cnt++; 133 } 134 135 /* 136 * if out of arguments, then print the specified resources 137 */ 138 139 if (optind == argc) { 140 if (!hard && !soft) { 141 soft++; 142 } 143 for (res = 0; res < RLIM_NLIMITS; res++) { 144 if (resources[res] == 0) { 145 continue; 146 } 147 if (getrlimit(res, &rlimit) < 0) { 148 continue; 149 } 150 if (cnt > 1) { 151 prs_buff(_gettext(rlimtab[res].name)); 152 prc_buff('('); 153 prs_buff(_gettext(rlimtab[res].scale)); 154 prc_buff(')'); 155 prc_buff(' '); 156 } 157 if (soft) { 158 if (rlimit.rlim_cur == RLIM_INFINITY) { 159 prs_buff(_gettext("unlimited")); 160 } else { 161 prull_buff(rlimit.rlim_cur / 162 rlimtab[res].divisor); 163 } 164 } 165 if (hard && soft) { 166 prc_buff(':'); 167 } 168 if (hard) { 169 if (rlimit.rlim_max == RLIM_INFINITY) { 170 prs_buff(_gettext("unlimited")); 171 } else { 172 prull_buff(rlimit.rlim_max / 173 rlimtab[res].divisor); 174 } 175 } 176 prc_buff('\n'); 177 } 178 goto err; 179 } 180 181 if (cnt > 1 || optind + 1 != argc) { 182 gfailure(usage, ulimuse); 183 goto err; 184 } 185 186 if (eq(argv[optind], "unlimited")) { 187 limit = RLIM_INFINITY; 188 } else { 189 args = argv[optind]; 190 191 new_limit = limit = 0; 192 do { 193 if (*args < '0' || *args > '9') { 194 snprintf(errargs, PATH_MAX-1, 195 "%s: %s", argv[0], args); 196 failure(errargs, badnum); 197 goto err; 198 } 199 /* Check for overflow! */ 200 new_limit = (limit * 10) + (*args - '0'); 201 if (new_limit >= limit) { 202 limit = new_limit; 203 } else { 204 snprintf(errargs, PATH_MAX-1, 205 "%s: %s", argv[0], args); 206 failure(errargs, badnum); 207 goto err; 208 } 209 } while (*++args); 210 211 /* Check for overflow! */ 212 new_limit = limit * rlimtab[res].divisor; 213 if (new_limit >= limit) { 214 limit = new_limit; 215 } else { 216 snprintf(errargs, PATH_MAX-1, 217 "%s: %s", argv[0], args); 218 failure(errargs, badnum); 219 goto err; 220 } 221 } 222 223 if (getrlimit(res, &rlimit) < 0) { 224 failure(argv[0], badnum); 225 goto err; 226 } 227 228 if (!hard && !soft) { 229 hard++; 230 soft++; 231 } 232 if (hard) { 233 rlimit.rlim_max = limit; 234 } 235 if (soft) { 236 rlimit.rlim_cur = limit; 237 } 238 239 if (setrlimit(res, &rlimit) < 0) { 240 snprintf(errargs, PATH_MAX-1, 241 "%s: %s", argv[0], argv[optind]); 242 failure(errargs, badulimit); 243 } 244 245 err: 246 optind = savoptind; 247 opterr = savopterr; 248 _sp = savsp; 249 optarg = savoptarg; 250 } 251