17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 217c478bd9Sstevel@tonic-gate */ 22*3d9df56cSakaplan /* 23*3d9df56cSakaplan * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24*3d9df56cSakaplan * Use is subject to license terms. 25*3d9df56cSakaplan */ 267c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 277c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate 30*3d9df56cSakaplan #pragma ident "%Z%%M% %I% %E% SMI" 317c478bd9Sstevel@tonic-gate 327c478bd9Sstevel@tonic-gate /* 337c478bd9Sstevel@tonic-gate * ulimit builtin 347c478bd9Sstevel@tonic-gate */ 357c478bd9Sstevel@tonic-gate 367c478bd9Sstevel@tonic-gate #include <sys/resource.h> 377c478bd9Sstevel@tonic-gate #include <stdlib.h> 387c478bd9Sstevel@tonic-gate #include "defs.h" 397c478bd9Sstevel@tonic-gate 407c478bd9Sstevel@tonic-gate /* 417c478bd9Sstevel@tonic-gate * order is important in this table! it is indexed by resource ID. 427c478bd9Sstevel@tonic-gate */ 437c478bd9Sstevel@tonic-gate 447c478bd9Sstevel@tonic-gate static struct rlimtab { 457c478bd9Sstevel@tonic-gate char *name; 467c478bd9Sstevel@tonic-gate char *scale; 477c478bd9Sstevel@tonic-gate rlim_t divisor; 487c478bd9Sstevel@tonic-gate } rlimtab[] = { 497c478bd9Sstevel@tonic-gate /* RLIMIT_CPU */ "time", "seconds", 1, 507c478bd9Sstevel@tonic-gate /* RLIMIT_FSIZE */ "file", "blocks", 512, 517c478bd9Sstevel@tonic-gate /* RLIMIT_DATA */ "data", "kbytes", 1024, 527c478bd9Sstevel@tonic-gate /* RLIMIT_STACK */ "stack", "kbytes", 1024, 537c478bd9Sstevel@tonic-gate /* RLIMIT_CORE */ "coredump", "blocks", 512, 547c478bd9Sstevel@tonic-gate /* RLIMIT_NOFILE */ "nofiles", "descriptors", 1, 557c478bd9Sstevel@tonic-gate /* RLIMIT_VMEM */ "memory", "kbytes", 1024, 567c478bd9Sstevel@tonic-gate }; 577c478bd9Sstevel@tonic-gate 587c478bd9Sstevel@tonic-gate void 597c478bd9Sstevel@tonic-gate sysulimit(int argc, char **argv) 607c478bd9Sstevel@tonic-gate { 617c478bd9Sstevel@tonic-gate extern int opterr, optind; 627c478bd9Sstevel@tonic-gate int savopterr, savoptind, savsp; 637c478bd9Sstevel@tonic-gate char *savoptarg; 647c478bd9Sstevel@tonic-gate char *args; 65*3d9df56cSakaplan char errargs[PATH_MAX]; 667c478bd9Sstevel@tonic-gate int hard, soft, cnt, c, res; 677c478bd9Sstevel@tonic-gate rlim_t limit, new_limit; 687c478bd9Sstevel@tonic-gate struct rlimit rlimit; 697c478bd9Sstevel@tonic-gate char resources[RLIM_NLIMITS]; 707c478bd9Sstevel@tonic-gate 717c478bd9Sstevel@tonic-gate for (res = 0; res < RLIM_NLIMITS; res++) { 727c478bd9Sstevel@tonic-gate resources[res] = 0; 737c478bd9Sstevel@tonic-gate } 747c478bd9Sstevel@tonic-gate 757c478bd9Sstevel@tonic-gate savoptind = optind; 767c478bd9Sstevel@tonic-gate savopterr = opterr; 777c478bd9Sstevel@tonic-gate savsp = _sp; 787c478bd9Sstevel@tonic-gate savoptarg = optarg; 797c478bd9Sstevel@tonic-gate optind = 1; 807c478bd9Sstevel@tonic-gate _sp = 1; 817c478bd9Sstevel@tonic-gate opterr = 0; 827c478bd9Sstevel@tonic-gate hard = 0; 837c478bd9Sstevel@tonic-gate soft = 0; 847c478bd9Sstevel@tonic-gate cnt = 0; 857c478bd9Sstevel@tonic-gate 867c478bd9Sstevel@tonic-gate while ((c = getopt(argc, argv, "HSacdfnstv")) != -1) { 877c478bd9Sstevel@tonic-gate switch (c) { 887c478bd9Sstevel@tonic-gate case 'S': 897c478bd9Sstevel@tonic-gate soft++; 907c478bd9Sstevel@tonic-gate continue; 917c478bd9Sstevel@tonic-gate case 'H': 927c478bd9Sstevel@tonic-gate hard++; 937c478bd9Sstevel@tonic-gate continue; 947c478bd9Sstevel@tonic-gate case 'a': 957c478bd9Sstevel@tonic-gate for (res = 0; res < RLIM_NLIMITS; res++) { 967c478bd9Sstevel@tonic-gate resources[res]++; 977c478bd9Sstevel@tonic-gate } 987c478bd9Sstevel@tonic-gate cnt = RLIM_NLIMITS; 997c478bd9Sstevel@tonic-gate continue; 1007c478bd9Sstevel@tonic-gate case 'c': 1017c478bd9Sstevel@tonic-gate res = RLIMIT_CORE; 1027c478bd9Sstevel@tonic-gate break; 1037c478bd9Sstevel@tonic-gate case 'd': 1047c478bd9Sstevel@tonic-gate res = RLIMIT_DATA; 1057c478bd9Sstevel@tonic-gate break; 1067c478bd9Sstevel@tonic-gate case 'f': 1077c478bd9Sstevel@tonic-gate res = RLIMIT_FSIZE; 1087c478bd9Sstevel@tonic-gate break; 1097c478bd9Sstevel@tonic-gate case 'n': 1107c478bd9Sstevel@tonic-gate res = RLIMIT_NOFILE; 1117c478bd9Sstevel@tonic-gate break; 1127c478bd9Sstevel@tonic-gate case 's': 1137c478bd9Sstevel@tonic-gate res = RLIMIT_STACK; 1147c478bd9Sstevel@tonic-gate break; 1157c478bd9Sstevel@tonic-gate case 't': 1167c478bd9Sstevel@tonic-gate res = RLIMIT_CPU; 1177c478bd9Sstevel@tonic-gate break; 1187c478bd9Sstevel@tonic-gate case 'v': 1197c478bd9Sstevel@tonic-gate res = RLIMIT_VMEM; 1207c478bd9Sstevel@tonic-gate break; 1217c478bd9Sstevel@tonic-gate case '?': 1227c478bd9Sstevel@tonic-gate failure(usage, ulimuse); 1237c478bd9Sstevel@tonic-gate goto err; 1247c478bd9Sstevel@tonic-gate } 1257c478bd9Sstevel@tonic-gate resources[res]++; 1267c478bd9Sstevel@tonic-gate cnt++; 1277c478bd9Sstevel@tonic-gate } 1287c478bd9Sstevel@tonic-gate 1297c478bd9Sstevel@tonic-gate if (cnt == 0) { 1307c478bd9Sstevel@tonic-gate resources[res = RLIMIT_FSIZE]++; 1317c478bd9Sstevel@tonic-gate cnt++; 1327c478bd9Sstevel@tonic-gate } 1337c478bd9Sstevel@tonic-gate 1347c478bd9Sstevel@tonic-gate /* 1357c478bd9Sstevel@tonic-gate * if out of arguments, then print the specified resources 1367c478bd9Sstevel@tonic-gate */ 1377c478bd9Sstevel@tonic-gate 1387c478bd9Sstevel@tonic-gate if (optind == argc) { 1397c478bd9Sstevel@tonic-gate if (!hard && !soft) { 1407c478bd9Sstevel@tonic-gate soft++; 1417c478bd9Sstevel@tonic-gate } 1427c478bd9Sstevel@tonic-gate for (res = 0; res < RLIM_NLIMITS; res++) { 1437c478bd9Sstevel@tonic-gate if (resources[res] == 0) { 1447c478bd9Sstevel@tonic-gate continue; 1457c478bd9Sstevel@tonic-gate } 1467c478bd9Sstevel@tonic-gate if (getrlimit(res, &rlimit) < 0) { 1477c478bd9Sstevel@tonic-gate continue; 1487c478bd9Sstevel@tonic-gate } 1497c478bd9Sstevel@tonic-gate if (cnt > 1) { 1507c478bd9Sstevel@tonic-gate prs_buff(rlimtab[res].name); 1517c478bd9Sstevel@tonic-gate prc_buff('('); 1527c478bd9Sstevel@tonic-gate prs_buff(rlimtab[res].scale); 1537c478bd9Sstevel@tonic-gate prc_buff(')'); 1547c478bd9Sstevel@tonic-gate prc_buff(' '); 1557c478bd9Sstevel@tonic-gate } 1567c478bd9Sstevel@tonic-gate if (soft) { 1577c478bd9Sstevel@tonic-gate if (rlimit.rlim_cur == RLIM_INFINITY) { 1587c478bd9Sstevel@tonic-gate prs_buff("unlimited"); 1597c478bd9Sstevel@tonic-gate } else { 1607c478bd9Sstevel@tonic-gate prull_buff(rlimit.rlim_cur / 1617c478bd9Sstevel@tonic-gate rlimtab[res].divisor); 1627c478bd9Sstevel@tonic-gate } 1637c478bd9Sstevel@tonic-gate } 1647c478bd9Sstevel@tonic-gate if (hard && soft) { 1657c478bd9Sstevel@tonic-gate prc_buff(':'); 1667c478bd9Sstevel@tonic-gate } 1677c478bd9Sstevel@tonic-gate if (hard) { 1687c478bd9Sstevel@tonic-gate if (rlimit.rlim_max == RLIM_INFINITY) { 1697c478bd9Sstevel@tonic-gate prs_buff("unlimited"); 1707c478bd9Sstevel@tonic-gate } else { 1717c478bd9Sstevel@tonic-gate prull_buff(rlimit.rlim_max / 1727c478bd9Sstevel@tonic-gate rlimtab[res].divisor); 1737c478bd9Sstevel@tonic-gate } 1747c478bd9Sstevel@tonic-gate } 1757c478bd9Sstevel@tonic-gate prc_buff('\n'); 1767c478bd9Sstevel@tonic-gate } 1777c478bd9Sstevel@tonic-gate goto err; 1787c478bd9Sstevel@tonic-gate } 1797c478bd9Sstevel@tonic-gate 1807c478bd9Sstevel@tonic-gate if (cnt > 1 || optind + 1 != argc) { 1817c478bd9Sstevel@tonic-gate failure(usage, ulimuse); 1827c478bd9Sstevel@tonic-gate goto err; 1837c478bd9Sstevel@tonic-gate } 1847c478bd9Sstevel@tonic-gate 1857c478bd9Sstevel@tonic-gate if (eq(argv[optind], "unlimited")) { 1867c478bd9Sstevel@tonic-gate limit = RLIM_INFINITY; 1877c478bd9Sstevel@tonic-gate } else { 1887c478bd9Sstevel@tonic-gate args = argv[optind]; 1897c478bd9Sstevel@tonic-gate 1907c478bd9Sstevel@tonic-gate new_limit = limit = 0; 1917c478bd9Sstevel@tonic-gate do { 1927c478bd9Sstevel@tonic-gate if (*args < '0' || *args > '9') { 193*3d9df56cSakaplan snprintf(errargs, PATH_MAX-1, 194*3d9df56cSakaplan "%s: %s", argv[0], args); 195*3d9df56cSakaplan failure(errargs, badnum); 1967c478bd9Sstevel@tonic-gate goto err; 1977c478bd9Sstevel@tonic-gate } 1987c478bd9Sstevel@tonic-gate /* Check for overflow! */ 1997c478bd9Sstevel@tonic-gate new_limit = (limit * 10) + (*args - '0'); 2007c478bd9Sstevel@tonic-gate if (new_limit >= limit) { 2017c478bd9Sstevel@tonic-gate limit = new_limit; 2027c478bd9Sstevel@tonic-gate } else { 203*3d9df56cSakaplan snprintf(errargs, PATH_MAX-1, 204*3d9df56cSakaplan "%s: %s", argv[0], args); 205*3d9df56cSakaplan failure(errargs, badnum); 2067c478bd9Sstevel@tonic-gate goto err; 2077c478bd9Sstevel@tonic-gate } 2087c478bd9Sstevel@tonic-gate } while (*++args); 2097c478bd9Sstevel@tonic-gate 2107c478bd9Sstevel@tonic-gate /* Check for overflow! */ 2117c478bd9Sstevel@tonic-gate new_limit = limit * rlimtab[res].divisor; 2127c478bd9Sstevel@tonic-gate if (new_limit >= limit) { 2137c478bd9Sstevel@tonic-gate limit = new_limit; 2147c478bd9Sstevel@tonic-gate } else { 215*3d9df56cSakaplan snprintf(errargs, PATH_MAX-1, 216*3d9df56cSakaplan "%s: %s", argv[0], args); 217*3d9df56cSakaplan failure(errargs, badnum); 2187c478bd9Sstevel@tonic-gate goto err; 2197c478bd9Sstevel@tonic-gate } 2207c478bd9Sstevel@tonic-gate } 2217c478bd9Sstevel@tonic-gate 2227c478bd9Sstevel@tonic-gate if (getrlimit(res, &rlimit) < 0) { 223*3d9df56cSakaplan failure(argv[0], badnum); 2247c478bd9Sstevel@tonic-gate goto err; 2257c478bd9Sstevel@tonic-gate } 2267c478bd9Sstevel@tonic-gate 2277c478bd9Sstevel@tonic-gate if (!hard && !soft) { 2287c478bd9Sstevel@tonic-gate hard++; 2297c478bd9Sstevel@tonic-gate soft++; 2307c478bd9Sstevel@tonic-gate } 2317c478bd9Sstevel@tonic-gate if (hard) { 2327c478bd9Sstevel@tonic-gate rlimit.rlim_max = limit; 2337c478bd9Sstevel@tonic-gate } 2347c478bd9Sstevel@tonic-gate if (soft) { 2357c478bd9Sstevel@tonic-gate rlimit.rlim_cur = limit; 2367c478bd9Sstevel@tonic-gate } 2377c478bd9Sstevel@tonic-gate 2387c478bd9Sstevel@tonic-gate if (setrlimit(res, &rlimit) < 0) { 239*3d9df56cSakaplan snprintf(errargs, PATH_MAX-1, 240*3d9df56cSakaplan "%s: %s", argv[0], argv[optind]); 241*3d9df56cSakaplan failure(errargs, badulimit); 2427c478bd9Sstevel@tonic-gate } 2437c478bd9Sstevel@tonic-gate 2447c478bd9Sstevel@tonic-gate err: 2457c478bd9Sstevel@tonic-gate optind = savoptind; 2467c478bd9Sstevel@tonic-gate opterr = savopterr; 2477c478bd9Sstevel@tonic-gate _sp = savsp; 2487c478bd9Sstevel@tonic-gate optarg = savoptarg; 2497c478bd9Sstevel@tonic-gate } 250