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