14b88c807SRodney W. Grimes /*- 24b88c807SRodney W. Grimes * Copyright (c) 1991, 1993 34b88c807SRodney W. Grimes * The Regents of the University of California. All rights reserved. 44b88c807SRodney W. Grimes * 54b88c807SRodney W. Grimes * This code is derived from software contributed to Berkeley by 64b88c807SRodney W. Grimes * Kenneth Almquist. 74b88c807SRodney W. Grimes * 84b88c807SRodney W. Grimes * Redistribution and use in source and binary forms, with or without 94b88c807SRodney W. Grimes * modification, are permitted provided that the following conditions 104b88c807SRodney W. Grimes * are met: 114b88c807SRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 124b88c807SRodney W. Grimes * notice, this list of conditions and the following disclaimer. 134b88c807SRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 144b88c807SRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 154b88c807SRodney W. Grimes * documentation and/or other materials provided with the distribution. 16*fbbd9655SWarner Losh * 3. Neither the name of the University nor the names of its contributors 174b88c807SRodney W. Grimes * may be used to endorse or promote products derived from this software 184b88c807SRodney W. Grimes * without specific prior written permission. 194b88c807SRodney W. Grimes * 204b88c807SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 214b88c807SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 224b88c807SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 234b88c807SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 244b88c807SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 254b88c807SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 264b88c807SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 274b88c807SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 284b88c807SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 294b88c807SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 304b88c807SRodney W. Grimes * SUCH DAMAGE. 314b88c807SRodney W. Grimes */ 324b88c807SRodney W. Grimes 334b88c807SRodney W. Grimes #ifndef lint 343d7b5b93SPhilippe Charnier #if 0 353d7b5b93SPhilippe Charnier static char sccsid[] = "@(#)miscbltin.c 8.4 (Berkeley) 5/4/95"; 363d7b5b93SPhilippe Charnier #endif 374b88c807SRodney W. Grimes #endif /* not lint */ 382749b141SDavid E. O'Brien #include <sys/cdefs.h> 392749b141SDavid E. O'Brien __FBSDID("$FreeBSD$"); 404b88c807SRodney W. Grimes 414b88c807SRodney W. Grimes /* 4246be34b9SKris Kennaway * Miscellaneous builtins. 434b88c807SRodney W. Grimes */ 444b88c807SRodney W. Grimes 45aa9caaf6SPeter Wemm #include <sys/types.h> 46aa9caaf6SPeter Wemm #include <sys/stat.h> 47aa9caaf6SPeter Wemm #include <sys/time.h> 48aa9caaf6SPeter Wemm #include <sys/resource.h> 49aa9caaf6SPeter Wemm #include <unistd.h> 5016992ff4SPeter Wemm #include <errno.h> 510c1661b7SMaxime Henrion #include <stdint.h> 524417f629SPeter Wemm #include <stdio.h> 531f40b47bSMartin Cracauer #include <stdlib.h> 54aa9caaf6SPeter Wemm 554b88c807SRodney W. Grimes #include "shell.h" 564b88c807SRodney W. Grimes #include "options.h" 574b88c807SRodney W. Grimes #include "var.h" 584b88c807SRodney W. Grimes #include "output.h" 594b88c807SRodney W. Grimes #include "memalloc.h" 604b88c807SRodney W. Grimes #include "error.h" 614b88c807SRodney W. Grimes #include "mystring.h" 6258570ac4SJilles Tjoelker #include "syntax.h" 63c4539460SJilles Tjoelker #include "trap.h" 644b88c807SRodney W. Grimes 654b88c807SRodney W. Grimes #undef eflag 664b88c807SRodney W. Grimes 6779ea0bd9SStefan Farfeleder int readcmd(int, char **); 6879ea0bd9SStefan Farfeleder int umaskcmd(int, char **); 6979ea0bd9SStefan Farfeleder int ulimitcmd(int, char **); 7079ea0bd9SStefan Farfeleder 714b88c807SRodney W. Grimes /* 728f0561ccSThomas Gellekum * The read builtin. The -r option causes backslashes to be treated like 738f0561ccSThomas Gellekum * ordinary characters. 744b88c807SRodney W. Grimes * 754b88c807SRodney W. Grimes * This uses unbuffered input, which may be avoidable in some cases. 76b6748ec2SStefan Farfeleder * 77b6748ec2SStefan Farfeleder * Note that if IFS=' :' then read x y should work so that: 78b6748ec2SStefan Farfeleder * 'a b' x='a', y='b' 79b6748ec2SStefan Farfeleder * ' a b ' x='a', y='b' 80b6748ec2SStefan Farfeleder * ':b' x='', y='b' 81b6748ec2SStefan Farfeleder * ':' x='', y='' 82b6748ec2SStefan Farfeleder * '::' x='', y='' 83b6748ec2SStefan Farfeleder * ': :' x='', y='' 84b6748ec2SStefan Farfeleder * ':::' x='', y='::' 85b6748ec2SStefan Farfeleder * ':b c:' x='', y='b c:' 864b88c807SRodney W. Grimes */ 874b88c807SRodney W. Grimes 88aa9caaf6SPeter Wemm int 895134c3f7SWarner Losh readcmd(int argc __unused, char **argv __unused) 90aa9caaf6SPeter Wemm { 914b88c807SRodney W. Grimes char **ap; 924b88c807SRodney W. Grimes int backslash; 934b88c807SRodney W. Grimes char c; 948f0561ccSThomas Gellekum int rflag; 954b88c807SRodney W. Grimes char *prompt; 96384aedabSJilles Tjoelker const char *ifs; 974b88c807SRodney W. Grimes char *p; 984b88c807SRodney W. Grimes int startword; 994b88c807SRodney W. Grimes int status; 1004b88c807SRodney W. Grimes int i; 101b6748ec2SStefan Farfeleder int is_ifs; 102b6748ec2SStefan Farfeleder int saveall = 0; 103f0688a48SJilles Tjoelker ptrdiff_t lastnonifs, lastnonifsws; 104afa53c8dSMike Smith struct timeval tv; 105afa53c8dSMike Smith char *tvptr; 106afa53c8dSMike Smith fd_set ifds; 107c4539460SJilles Tjoelker ssize_t nread; 108c4539460SJilles Tjoelker int sig; 1094b88c807SRodney W. Grimes 1108f0561ccSThomas Gellekum rflag = 0; 1114b88c807SRodney W. Grimes prompt = NULL; 112afa53c8dSMike Smith tv.tv_sec = -1; 113afa53c8dSMike Smith tv.tv_usec = 0; 1148f0561ccSThomas Gellekum while ((i = nextopt("erp:t:")) != '\0') { 115afa53c8dSMike Smith switch(i) { 116afa53c8dSMike Smith case 'p': 117f01e3d0cSMartin Cracauer prompt = shoptarg; 118afa53c8dSMike Smith break; 119afa53c8dSMike Smith case 'e': 1208f0561ccSThomas Gellekum break; 1218f0561ccSThomas Gellekum case 'r': 1228f0561ccSThomas Gellekum rflag = 1; 123afa53c8dSMike Smith break; 124afa53c8dSMike Smith case 't': 125f01e3d0cSMartin Cracauer tv.tv_sec = strtol(shoptarg, &tvptr, 0); 126f01e3d0cSMartin Cracauer if (tvptr == shoptarg) 127afa53c8dSMike Smith error("timeout value"); 128afa53c8dSMike Smith switch(*tvptr) { 129afa53c8dSMike Smith case 0: 130afa53c8dSMike Smith case 's': 131afa53c8dSMike Smith break; 132afa53c8dSMike Smith case 'h': 133afa53c8dSMike Smith tv.tv_sec *= 60; 134afa53c8dSMike Smith /* FALLTHROUGH */ 135afa53c8dSMike Smith case 'm': 136afa53c8dSMike Smith tv.tv_sec *= 60; 137afa53c8dSMike Smith break; 138afa53c8dSMike Smith default: 139afa53c8dSMike Smith error("timeout unit"); 140afa53c8dSMike Smith } 141afa53c8dSMike Smith break; 142afa53c8dSMike Smith } 1434b88c807SRodney W. Grimes } 1444b88c807SRodney W. Grimes if (prompt && isatty(0)) { 1454b88c807SRodney W. Grimes out2str(prompt); 1464b88c807SRodney W. Grimes flushall(); 1474b88c807SRodney W. Grimes } 1484b88c807SRodney W. Grimes if (*(ap = argptr) == NULL) 1494b88c807SRodney W. Grimes error("arg count"); 1504b88c807SRodney W. Grimes if ((ifs = bltinlookup("IFS", 1)) == NULL) 15186d8da5dSStefan Farfeleder ifs = " \t\n"; 152afa53c8dSMike Smith 153afa53c8dSMike Smith if (tv.tv_sec >= 0) { 154afa53c8dSMike Smith /* 155afa53c8dSMike Smith * Wait for something to become available. 156afa53c8dSMike Smith */ 157afa53c8dSMike Smith FD_ZERO(&ifds); 158afa53c8dSMike Smith FD_SET(0, &ifds); 159afa53c8dSMike Smith status = select(1, &ifds, NULL, NULL, &tv); 160afa53c8dSMike Smith /* 161afa53c8dSMike Smith * If there's nothing ready, return an error. 162afa53c8dSMike Smith */ 163c4539460SJilles Tjoelker if (status <= 0) { 164c4539460SJilles Tjoelker sig = pendingsig; 165c4539460SJilles Tjoelker return (128 + (sig != 0 ? sig : SIGALRM)); 166c4539460SJilles Tjoelker } 167afa53c8dSMike Smith } 168afa53c8dSMike Smith 1694b88c807SRodney W. Grimes status = 0; 170b6748ec2SStefan Farfeleder startword = 2; 1714b88c807SRodney W. Grimes backslash = 0; 1724b88c807SRodney W. Grimes STARTSTACKSTR(p); 173f0688a48SJilles Tjoelker lastnonifs = lastnonifsws = -1; 1744b88c807SRodney W. Grimes for (;;) { 175c4539460SJilles Tjoelker nread = read(STDIN_FILENO, &c, 1); 176c4539460SJilles Tjoelker if (nread == -1) { 177c4539460SJilles Tjoelker if (errno == EINTR) { 178c4539460SJilles Tjoelker sig = pendingsig; 179c4539460SJilles Tjoelker if (sig == 0) 180c4539460SJilles Tjoelker continue; 181c4539460SJilles Tjoelker status = 128 + sig; 182c4539460SJilles Tjoelker break; 183c4539460SJilles Tjoelker } 184c4539460SJilles Tjoelker warning("read error: %s", strerror(errno)); 185c4539460SJilles Tjoelker status = 2; 186c4539460SJilles Tjoelker break; 187c4539460SJilles Tjoelker } else if (nread != 1) { 1884b88c807SRodney W. Grimes status = 1; 1894b88c807SRodney W. Grimes break; 1904b88c807SRodney W. Grimes } 1914b88c807SRodney W. Grimes if (c == '\0') 1924b88c807SRodney W. Grimes continue; 1939d37e157SJilles Tjoelker CHECKSTRSPACE(1, p); 1944b88c807SRodney W. Grimes if (backslash) { 1954b88c807SRodney W. Grimes backslash = 0; 1964b6578dcSJilles Tjoelker if (c != '\n') { 197917fdfb1SJilles Tjoelker startword = 0; 198f0688a48SJilles Tjoelker lastnonifs = lastnonifsws = p - stackblock(); 1999d37e157SJilles Tjoelker USTPUTC(c, p); 2004b6578dcSJilles Tjoelker } 2014b88c807SRodney W. Grimes continue; 2024b88c807SRodney W. Grimes } 2038f0561ccSThomas Gellekum if (!rflag && c == '\\') { 2044b88c807SRodney W. Grimes backslash++; 2054b88c807SRodney W. Grimes continue; 2064b88c807SRodney W. Grimes } 2074b88c807SRodney W. Grimes if (c == '\n') 2084b88c807SRodney W. Grimes break; 209b6748ec2SStefan Farfeleder if (strchr(ifs, c)) 210b6748ec2SStefan Farfeleder is_ifs = strchr(" \t\n", c) ? 1 : 2; 211b6748ec2SStefan Farfeleder else 212b6748ec2SStefan Farfeleder is_ifs = 0; 213b6748ec2SStefan Farfeleder 214b6748ec2SStefan Farfeleder if (startword != 0) { 215b6748ec2SStefan Farfeleder if (is_ifs == 1) { 216b6748ec2SStefan Farfeleder /* Ignore leading IFS whitespace */ 217b6748ec2SStefan Farfeleder if (saveall) 2189d37e157SJilles Tjoelker USTPUTC(c, p); 2194b88c807SRodney W. Grimes continue; 2204b88c807SRodney W. Grimes } 221b6748ec2SStefan Farfeleder if (is_ifs == 2 && startword == 1) { 222b6748ec2SStefan Farfeleder /* Only one non-whitespace IFS per word */ 223b6748ec2SStefan Farfeleder startword = 2; 224f0688a48SJilles Tjoelker if (saveall) { 225f0688a48SJilles Tjoelker lastnonifsws = p - stackblock(); 2269d37e157SJilles Tjoelker USTPUTC(c, p); 227f0688a48SJilles Tjoelker } 228b6748ec2SStefan Farfeleder continue; 229b6748ec2SStefan Farfeleder } 230b6748ec2SStefan Farfeleder } 231b6748ec2SStefan Farfeleder 232b6748ec2SStefan Farfeleder if (is_ifs == 0) { 233b6748ec2SStefan Farfeleder /* append this character to the current variable */ 2344b88c807SRodney W. Grimes startword = 0; 235b6748ec2SStefan Farfeleder if (saveall) 236b6748ec2SStefan Farfeleder /* Not just a spare terminator */ 237b6748ec2SStefan Farfeleder saveall++; 238f0688a48SJilles Tjoelker lastnonifs = lastnonifsws = p - stackblock(); 2399d37e157SJilles Tjoelker USTPUTC(c, p); 240b6748ec2SStefan Farfeleder continue; 241b6748ec2SStefan Farfeleder } 242b6748ec2SStefan Farfeleder 243b6748ec2SStefan Farfeleder /* end of variable... */ 244b6748ec2SStefan Farfeleder startword = is_ifs; 245b6748ec2SStefan Farfeleder 246b6748ec2SStefan Farfeleder if (ap[1] == NULL) { 247b6748ec2SStefan Farfeleder /* Last variable needs all IFS chars */ 248b6748ec2SStefan Farfeleder saveall++; 249f0688a48SJilles Tjoelker if (is_ifs == 2) 250f0688a48SJilles Tjoelker lastnonifsws = p - stackblock(); 2519d37e157SJilles Tjoelker USTPUTC(c, p); 252b6748ec2SStefan Farfeleder continue; 253b6748ec2SStefan Farfeleder } 254b6748ec2SStefan Farfeleder 2554b88c807SRodney W. Grimes STACKSTRNUL(p); 2564b88c807SRodney W. Grimes setvar(*ap, stackblock(), 0); 2574b88c807SRodney W. Grimes ap++; 2584b88c807SRodney W. Grimes STARTSTACKSTR(p); 259f0688a48SJilles Tjoelker lastnonifs = lastnonifsws = -1; 2604b88c807SRodney W. Grimes } 2614b88c807SRodney W. Grimes STACKSTRNUL(p); 262b6748ec2SStefan Farfeleder 263f0688a48SJilles Tjoelker /* 264f0688a48SJilles Tjoelker * Remove trailing IFS chars: always remove whitespace, don't remove 265f0688a48SJilles Tjoelker * non-whitespace unless it was naked 266f0688a48SJilles Tjoelker */ 267f0688a48SJilles Tjoelker if (saveall <= 1) 268f0688a48SJilles Tjoelker lastnonifsws = lastnonifs; 269f0688a48SJilles Tjoelker stackblock()[lastnonifsws + 1] = '\0'; 2704b88c807SRodney W. Grimes setvar(*ap, stackblock(), 0); 271b6748ec2SStefan Farfeleder 272b6748ec2SStefan Farfeleder /* Set any remaining args to "" */ 2734b88c807SRodney W. Grimes while (*++ap != NULL) 274781bfb5aSJilles Tjoelker setvar(*ap, "", 0); 2754b88c807SRodney W. Grimes return status; 2764b88c807SRodney W. Grimes } 2774b88c807SRodney W. Grimes 2784b88c807SRodney W. Grimes 2794b88c807SRodney W. Grimes 280aa9caaf6SPeter Wemm int 281384aedabSJilles Tjoelker umaskcmd(int argc __unused, char **argv __unused) 282aa9caaf6SPeter Wemm { 283aa9caaf6SPeter Wemm char *ap; 2844b88c807SRodney W. Grimes int mask; 2854b88c807SRodney W. Grimes int i; 286aa9caaf6SPeter Wemm int symbolic_mode = 0; 2874b88c807SRodney W. Grimes 288aa9caaf6SPeter Wemm while ((i = nextopt("S")) != '\0') { 289aa9caaf6SPeter Wemm symbolic_mode = 1; 290aa9caaf6SPeter Wemm } 291aa9caaf6SPeter Wemm 2924b88c807SRodney W. Grimes INTOFF; 2934b88c807SRodney W. Grimes mask = umask(0); 2944b88c807SRodney W. Grimes umask(mask); 2954b88c807SRodney W. Grimes INTON; 296aa9caaf6SPeter Wemm 297aa9caaf6SPeter Wemm if ((ap = *argptr) == NULL) { 298aa9caaf6SPeter Wemm if (symbolic_mode) { 299aa9caaf6SPeter Wemm char u[4], g[4], o[4]; 300aa9caaf6SPeter Wemm 301aa9caaf6SPeter Wemm i = 0; 302aa9caaf6SPeter Wemm if ((mask & S_IRUSR) == 0) 303aa9caaf6SPeter Wemm u[i++] = 'r'; 304aa9caaf6SPeter Wemm if ((mask & S_IWUSR) == 0) 305aa9caaf6SPeter Wemm u[i++] = 'w'; 306aa9caaf6SPeter Wemm if ((mask & S_IXUSR) == 0) 307aa9caaf6SPeter Wemm u[i++] = 'x'; 308aa9caaf6SPeter Wemm u[i] = '\0'; 309aa9caaf6SPeter Wemm 310aa9caaf6SPeter Wemm i = 0; 311aa9caaf6SPeter Wemm if ((mask & S_IRGRP) == 0) 312aa9caaf6SPeter Wemm g[i++] = 'r'; 313aa9caaf6SPeter Wemm if ((mask & S_IWGRP) == 0) 314aa9caaf6SPeter Wemm g[i++] = 'w'; 315aa9caaf6SPeter Wemm if ((mask & S_IXGRP) == 0) 316aa9caaf6SPeter Wemm g[i++] = 'x'; 317aa9caaf6SPeter Wemm g[i] = '\0'; 318aa9caaf6SPeter Wemm 319aa9caaf6SPeter Wemm i = 0; 320aa9caaf6SPeter Wemm if ((mask & S_IROTH) == 0) 321aa9caaf6SPeter Wemm o[i++] = 'r'; 322aa9caaf6SPeter Wemm if ((mask & S_IWOTH) == 0) 323aa9caaf6SPeter Wemm o[i++] = 'w'; 324aa9caaf6SPeter Wemm if ((mask & S_IXOTH) == 0) 325aa9caaf6SPeter Wemm o[i++] = 'x'; 326aa9caaf6SPeter Wemm o[i] = '\0'; 327aa9caaf6SPeter Wemm 328aa9caaf6SPeter Wemm out1fmt("u=%s,g=%s,o=%s\n", u, g, o); 3294b88c807SRodney W. Grimes } else { 330aa9caaf6SPeter Wemm out1fmt("%.4o\n", mask); 331aa9caaf6SPeter Wemm } 332aa9caaf6SPeter Wemm } else { 33358570ac4SJilles Tjoelker if (is_digit(*ap)) { 3344b88c807SRodney W. Grimes mask = 0; 3354b88c807SRodney W. Grimes do { 336aa9caaf6SPeter Wemm if (*ap >= '8' || *ap < '0') 337e4c880afSStefan Farfeleder error("Illegal number: %s", *argptr); 338aa9caaf6SPeter Wemm mask = (mask << 3) + (*ap - '0'); 339aa9caaf6SPeter Wemm } while (*++ap != '\0'); 3404b88c807SRodney W. Grimes umask(mask); 341aa9caaf6SPeter Wemm } else { 342aa9caaf6SPeter Wemm void *set; 343670528cdSStefan Farfeleder INTOFF; 34474136dc3SPedro F. Giffuni if ((set = setmode (ap)) == NULL) 345aa9caaf6SPeter Wemm error("Illegal number: %s", ap); 346aa9caaf6SPeter Wemm 347aa9caaf6SPeter Wemm mask = getmode (set, ~mask & 0777); 348aa9caaf6SPeter Wemm umask(~mask & 0777); 349a207266eSWarner Losh free(set); 350670528cdSStefan Farfeleder INTON; 351aa9caaf6SPeter Wemm } 3524b88c807SRodney W. Grimes } 3534b88c807SRodney W. Grimes return 0; 3544b88c807SRodney W. Grimes } 3557a2afe64SJoerg Wunsch 356aa9caaf6SPeter Wemm /* 357aa9caaf6SPeter Wemm * ulimit builtin 358aa9caaf6SPeter Wemm * 359aa9caaf6SPeter Wemm * This code, originally by Doug Gwyn, Doug Kingston, Eric Gisin, and 360aa9caaf6SPeter Wemm * Michael Rendell was ripped from pdksh 5.0.8 and hacked for use with 361aa9caaf6SPeter Wemm * ash by J.T. Conklin. 362aa9caaf6SPeter Wemm * 363aa9caaf6SPeter Wemm * Public domain. 364aa9caaf6SPeter Wemm */ 3657a2afe64SJoerg Wunsch 366aa9caaf6SPeter Wemm struct limits { 367aa9caaf6SPeter Wemm const char *name; 36816992ff4SPeter Wemm const char *units; 369aa9caaf6SPeter Wemm int cmd; 370aa9caaf6SPeter Wemm int factor; /* multiply by to get rlim_{cur,max} values */ 371aa9caaf6SPeter Wemm char option; 3727a2afe64SJoerg Wunsch }; 3737a2afe64SJoerg Wunsch 374aa9caaf6SPeter Wemm static const struct limits limits[] = { 375aa9caaf6SPeter Wemm #ifdef RLIMIT_CPU 37616992ff4SPeter Wemm { "cpu time", "seconds", RLIMIT_CPU, 1, 't' }, 377aa9caaf6SPeter Wemm #endif 378aa9caaf6SPeter Wemm #ifdef RLIMIT_FSIZE 37916992ff4SPeter Wemm { "file size", "512-blocks", RLIMIT_FSIZE, 512, 'f' }, 380aa9caaf6SPeter Wemm #endif 381aa9caaf6SPeter Wemm #ifdef RLIMIT_DATA 38216992ff4SPeter Wemm { "data seg size", "kbytes", RLIMIT_DATA, 1024, 'd' }, 383aa9caaf6SPeter Wemm #endif 384aa9caaf6SPeter Wemm #ifdef RLIMIT_STACK 38516992ff4SPeter Wemm { "stack size", "kbytes", RLIMIT_STACK, 1024, 's' }, 386aa9caaf6SPeter Wemm #endif 387aa9caaf6SPeter Wemm #ifdef RLIMIT_CORE 38816992ff4SPeter Wemm { "core file size", "512-blocks", RLIMIT_CORE, 512, 'c' }, 389aa9caaf6SPeter Wemm #endif 390aa9caaf6SPeter Wemm #ifdef RLIMIT_RSS 39116992ff4SPeter Wemm { "max memory size", "kbytes", RLIMIT_RSS, 1024, 'm' }, 392aa9caaf6SPeter Wemm #endif 393aa9caaf6SPeter Wemm #ifdef RLIMIT_MEMLOCK 39416992ff4SPeter Wemm { "locked memory", "kbytes", RLIMIT_MEMLOCK, 1024, 'l' }, 395aa9caaf6SPeter Wemm #endif 396aa9caaf6SPeter Wemm #ifdef RLIMIT_NPROC 39716992ff4SPeter Wemm { "max user processes", (char *)0, RLIMIT_NPROC, 1, 'u' }, 398aa9caaf6SPeter Wemm #endif 399aa9caaf6SPeter Wemm #ifdef RLIMIT_NOFILE 40016992ff4SPeter Wemm { "open files", (char *)0, RLIMIT_NOFILE, 1, 'n' }, 401aa9caaf6SPeter Wemm #endif 402aa9caaf6SPeter Wemm #ifdef RLIMIT_VMEM 40316992ff4SPeter Wemm { "virtual mem size", "kbytes", RLIMIT_VMEM, 1024, 'v' }, 404aa9caaf6SPeter Wemm #endif 405aa9caaf6SPeter Wemm #ifdef RLIMIT_SWAP 40616992ff4SPeter Wemm { "swap limit", "kbytes", RLIMIT_SWAP, 1024, 'w' }, 407aa9caaf6SPeter Wemm #endif 4087cde774dSBrian Feldman #ifdef RLIMIT_SBSIZE 409535c8d93SJilles Tjoelker { "socket buffer size", "bytes", RLIMIT_SBSIZE, 1, 'b' }, 4107cde774dSBrian Feldman #endif 411bc093719SEd Schouten #ifdef RLIMIT_NPTS 412bc093719SEd Schouten { "pseudo-terminals", (char *)0, RLIMIT_NPTS, 1, 'p' }, 413bc093719SEd Schouten #endif 41485a0ddfdSKonstantin Belousov #ifdef RLIMIT_KQUEUES 41585a0ddfdSKonstantin Belousov { "kqueues", (char *)0, RLIMIT_KQUEUES, 1, 'k' }, 41685a0ddfdSKonstantin Belousov #endif 4171bdbd705SKonstantin Belousov #ifdef RLIMIT_UMTXP 418535c8d93SJilles Tjoelker { "umtx shared locks", (char *)0, RLIMIT_UMTXP, 1, 'o' }, 4191bdbd705SKonstantin Belousov #endif 42016992ff4SPeter Wemm { (char *) 0, (char *)0, 0, 0, '\0' } 4217a2afe64SJoerg Wunsch }; 4227a2afe64SJoerg Wunsch 4232ef146f1SJilles Tjoelker enum limithow { SOFT = 0x1, HARD = 0x2 }; 4242ef146f1SJilles Tjoelker 4252ef146f1SJilles Tjoelker static void 4262ef146f1SJilles Tjoelker printlimit(enum limithow how, const struct rlimit *limit, 4272ef146f1SJilles Tjoelker const struct limits *l) 4282ef146f1SJilles Tjoelker { 4292ef146f1SJilles Tjoelker rlim_t val = 0; 4302ef146f1SJilles Tjoelker 4312ef146f1SJilles Tjoelker if (how & SOFT) 4322ef146f1SJilles Tjoelker val = limit->rlim_cur; 4332ef146f1SJilles Tjoelker else if (how & HARD) 4342ef146f1SJilles Tjoelker val = limit->rlim_max; 4352ef146f1SJilles Tjoelker if (val == RLIM_INFINITY) 4362ef146f1SJilles Tjoelker out1str("unlimited\n"); 4372ef146f1SJilles Tjoelker else 4382ef146f1SJilles Tjoelker { 4392ef146f1SJilles Tjoelker val /= l->factor; 4402ef146f1SJilles Tjoelker out1fmt("%jd\n", (intmax_t)val); 4412ef146f1SJilles Tjoelker } 4422ef146f1SJilles Tjoelker } 4432ef146f1SJilles Tjoelker 444aa9caaf6SPeter Wemm int 4455134c3f7SWarner Losh ulimitcmd(int argc __unused, char **argv __unused) 446aa9caaf6SPeter Wemm { 4470c1661b7SMaxime Henrion rlim_t val = 0; 4482ef146f1SJilles Tjoelker enum limithow how = SOFT | HARD; 449aa9caaf6SPeter Wemm const struct limits *l; 450aa9caaf6SPeter Wemm int set, all = 0; 451aa9caaf6SPeter Wemm int optc, what; 452aa9caaf6SPeter Wemm struct rlimit limit; 4537a2afe64SJoerg Wunsch 454aa9caaf6SPeter Wemm what = 'f'; 455250d9fd8SKonstantin Belousov while ((optc = nextopt("HSatfdsmcnuvlbpwko")) != '\0') 456aa9caaf6SPeter Wemm switch (optc) { 4577a2afe64SJoerg Wunsch case 'H': 458aa9caaf6SPeter Wemm how = HARD; 4597a2afe64SJoerg Wunsch break; 4607a2afe64SJoerg Wunsch case 'S': 461aa9caaf6SPeter Wemm how = SOFT; 4627a2afe64SJoerg Wunsch break; 4637a2afe64SJoerg Wunsch case 'a': 464aa9caaf6SPeter Wemm all = 1; 4657a2afe64SJoerg Wunsch break; 466aa9caaf6SPeter Wemm default: 467aa9caaf6SPeter Wemm what = optc; 4687a2afe64SJoerg Wunsch } 4697a2afe64SJoerg Wunsch 470aa9caaf6SPeter Wemm for (l = limits; l->name && l->option != what; l++) 471aa9caaf6SPeter Wemm ; 472aa9caaf6SPeter Wemm if (!l->name) 473abe2dc61STim J. Robbins error("internal error (%c)", what); 4747a2afe64SJoerg Wunsch 475aa9caaf6SPeter Wemm set = *argptr ? 1 : 0; 476aa9caaf6SPeter Wemm if (set) { 477aa9caaf6SPeter Wemm char *p = *argptr; 478aa9caaf6SPeter Wemm 479aa9caaf6SPeter Wemm if (all || argptr[1]) 480abe2dc61STim J. Robbins error("too many arguments"); 481aa9caaf6SPeter Wemm if (strcmp(p, "unlimited") == 0) 4827a2afe64SJoerg Wunsch val = RLIM_INFINITY; 4837a2afe64SJoerg Wunsch else { 4842d70c637SJilles Tjoelker char *end; 4852d70c637SJilles Tjoelker uintmax_t uval; 486aa9caaf6SPeter Wemm 4872d70c637SJilles Tjoelker if (*p < '0' || *p > '9') 488abe2dc61STim J. Robbins error("bad number"); 4892d70c637SJilles Tjoelker errno = 0; 4902d70c637SJilles Tjoelker uval = strtoumax(p, &end, 10); 4912d70c637SJilles Tjoelker if (errno != 0 || *end != '\0') 4922d70c637SJilles Tjoelker error("bad number"); 4932d70c637SJilles Tjoelker if (uval > UINTMAX_MAX / l->factor) 4942d70c637SJilles Tjoelker error("bad number"); 4952d70c637SJilles Tjoelker uval *= l->factor; 4962d70c637SJilles Tjoelker val = (rlim_t)uval; 4972d70c637SJilles Tjoelker if (val < 0 || (uintmax_t)val != uval || 4982d70c637SJilles Tjoelker val == RLIM_INFINITY) 4992d70c637SJilles Tjoelker error("bad number"); 500aa9caaf6SPeter Wemm } 501aa9caaf6SPeter Wemm } 502aa9caaf6SPeter Wemm if (all) { 503aa9caaf6SPeter Wemm for (l = limits; l->name; l++) { 50416992ff4SPeter Wemm char optbuf[40]; 50516992ff4SPeter Wemm if (getrlimit(l->cmd, &limit) < 0) 506abe2dc61STim J. Robbins error("can't get limit: %s", strerror(errno)); 507aa9caaf6SPeter Wemm 50816992ff4SPeter Wemm if (l->units) 50916992ff4SPeter Wemm snprintf(optbuf, sizeof(optbuf), 5104e4e0959SPeter Wemm "(%s, -%c) ", l->units, l->option); 51116992ff4SPeter Wemm else 51216992ff4SPeter Wemm snprintf(optbuf, sizeof(optbuf), 5134e4e0959SPeter Wemm "(-%c) ", l->option); 5144e4e0959SPeter Wemm out1fmt("%-18s %18s ", l->name, optbuf); 5152ef146f1SJilles Tjoelker printlimit(how, &limit, l); 5167a2afe64SJoerg Wunsch } 5177a2afe64SJoerg Wunsch return 0; 5187a2afe64SJoerg Wunsch } 519aa9caaf6SPeter Wemm 52016992ff4SPeter Wemm if (getrlimit(l->cmd, &limit) < 0) 521abe2dc61STim J. Robbins error("can't get limit: %s", strerror(errno)); 522aa9caaf6SPeter Wemm if (set) { 523aa9caaf6SPeter Wemm if (how & SOFT) 524aa9caaf6SPeter Wemm limit.rlim_cur = val; 525aa9caaf6SPeter Wemm if (how & HARD) 526aa9caaf6SPeter Wemm limit.rlim_max = val; 527aa9caaf6SPeter Wemm if (setrlimit(l->cmd, &limit) < 0) 528abe2dc61STim J. Robbins error("bad limit: %s", strerror(errno)); 5292ef146f1SJilles Tjoelker } else 5302ef146f1SJilles Tjoelker printlimit(how, &limit, l); 531aa9caaf6SPeter Wemm return 0; 532aa9caaf6SPeter Wemm } 533