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. 164b88c807SRodney W. Grimes * 4. 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; 103afa53c8dSMike Smith struct timeval tv; 104afa53c8dSMike Smith char *tvptr; 105afa53c8dSMike Smith fd_set ifds; 106c4539460SJilles Tjoelker ssize_t nread; 107c4539460SJilles Tjoelker int sig; 1084b88c807SRodney W. Grimes 1098f0561ccSThomas Gellekum rflag = 0; 1104b88c807SRodney W. Grimes prompt = NULL; 111afa53c8dSMike Smith tv.tv_sec = -1; 112afa53c8dSMike Smith tv.tv_usec = 0; 1138f0561ccSThomas Gellekum while ((i = nextopt("erp:t:")) != '\0') { 114afa53c8dSMike Smith switch(i) { 115afa53c8dSMike Smith case 'p': 116f01e3d0cSMartin Cracauer prompt = shoptarg; 117afa53c8dSMike Smith break; 118afa53c8dSMike Smith case 'e': 1198f0561ccSThomas Gellekum break; 1208f0561ccSThomas Gellekum case 'r': 1218f0561ccSThomas Gellekum rflag = 1; 122afa53c8dSMike Smith break; 123afa53c8dSMike Smith case 't': 124f01e3d0cSMartin Cracauer tv.tv_sec = strtol(shoptarg, &tvptr, 0); 125f01e3d0cSMartin Cracauer if (tvptr == shoptarg) 126afa53c8dSMike Smith error("timeout value"); 127afa53c8dSMike Smith switch(*tvptr) { 128afa53c8dSMike Smith case 0: 129afa53c8dSMike Smith case 's': 130afa53c8dSMike Smith break; 131afa53c8dSMike Smith case 'h': 132afa53c8dSMike Smith tv.tv_sec *= 60; 133afa53c8dSMike Smith /* FALLTHROUGH */ 134afa53c8dSMike Smith case 'm': 135afa53c8dSMike Smith tv.tv_sec *= 60; 136afa53c8dSMike Smith break; 137afa53c8dSMike Smith default: 138afa53c8dSMike Smith error("timeout unit"); 139afa53c8dSMike Smith } 140afa53c8dSMike Smith break; 141afa53c8dSMike Smith } 1424b88c807SRodney W. Grimes } 1434b88c807SRodney W. Grimes if (prompt && isatty(0)) { 1444b88c807SRodney W. Grimes out2str(prompt); 1454b88c807SRodney W. Grimes flushall(); 1464b88c807SRodney W. Grimes } 1474b88c807SRodney W. Grimes if (*(ap = argptr) == NULL) 1484b88c807SRodney W. Grimes error("arg count"); 1494b88c807SRodney W. Grimes if ((ifs = bltinlookup("IFS", 1)) == NULL) 15086d8da5dSStefan Farfeleder ifs = " \t\n"; 151afa53c8dSMike Smith 152afa53c8dSMike Smith if (tv.tv_sec >= 0) { 153afa53c8dSMike Smith /* 154afa53c8dSMike Smith * Wait for something to become available. 155afa53c8dSMike Smith */ 156afa53c8dSMike Smith FD_ZERO(&ifds); 157afa53c8dSMike Smith FD_SET(0, &ifds); 158afa53c8dSMike Smith status = select(1, &ifds, NULL, NULL, &tv); 159afa53c8dSMike Smith /* 160afa53c8dSMike Smith * If there's nothing ready, return an error. 161afa53c8dSMike Smith */ 162c4539460SJilles Tjoelker if (status <= 0) { 163c4539460SJilles Tjoelker sig = pendingsig; 164c4539460SJilles Tjoelker return (128 + (sig != 0 ? sig : SIGALRM)); 165c4539460SJilles Tjoelker } 166afa53c8dSMike Smith } 167afa53c8dSMike Smith 1684b88c807SRodney W. Grimes status = 0; 169b6748ec2SStefan Farfeleder startword = 2; 1704b88c807SRodney W. Grimes backslash = 0; 1714b88c807SRodney W. Grimes STARTSTACKSTR(p); 1724b88c807SRodney W. Grimes for (;;) { 173c4539460SJilles Tjoelker nread = read(STDIN_FILENO, &c, 1); 174c4539460SJilles Tjoelker if (nread == -1) { 175c4539460SJilles Tjoelker if (errno == EINTR) { 176c4539460SJilles Tjoelker sig = pendingsig; 177c4539460SJilles Tjoelker if (sig == 0) 178c4539460SJilles Tjoelker continue; 179c4539460SJilles Tjoelker status = 128 + sig; 180c4539460SJilles Tjoelker break; 181c4539460SJilles Tjoelker } 182c4539460SJilles Tjoelker warning("read error: %s", strerror(errno)); 183c4539460SJilles Tjoelker status = 2; 184c4539460SJilles Tjoelker break; 185c4539460SJilles Tjoelker } else if (nread != 1) { 1864b88c807SRodney W. Grimes status = 1; 1874b88c807SRodney W. Grimes break; 1884b88c807SRodney W. Grimes } 1894b88c807SRodney W. Grimes if (c == '\0') 1904b88c807SRodney W. Grimes continue; 1919d37e157SJilles Tjoelker CHECKSTRSPACE(1, p); 1924b88c807SRodney W. Grimes if (backslash) { 1934b88c807SRodney W. Grimes backslash = 0; 194*4b6578dcSJilles Tjoelker if (c != '\n') { 195917fdfb1SJilles Tjoelker startword = 0; 1969d37e157SJilles Tjoelker USTPUTC(c, p); 197*4b6578dcSJilles Tjoelker } 1984b88c807SRodney W. Grimes continue; 1994b88c807SRodney W. Grimes } 2008f0561ccSThomas Gellekum if (!rflag && c == '\\') { 2014b88c807SRodney W. Grimes backslash++; 2024b88c807SRodney W. Grimes continue; 2034b88c807SRodney W. Grimes } 2044b88c807SRodney W. Grimes if (c == '\n') 2054b88c807SRodney W. Grimes break; 206b6748ec2SStefan Farfeleder if (strchr(ifs, c)) 207b6748ec2SStefan Farfeleder is_ifs = strchr(" \t\n", c) ? 1 : 2; 208b6748ec2SStefan Farfeleder else 209b6748ec2SStefan Farfeleder is_ifs = 0; 210b6748ec2SStefan Farfeleder 211b6748ec2SStefan Farfeleder if (startword != 0) { 212b6748ec2SStefan Farfeleder if (is_ifs == 1) { 213b6748ec2SStefan Farfeleder /* Ignore leading IFS whitespace */ 214b6748ec2SStefan Farfeleder if (saveall) 2159d37e157SJilles Tjoelker USTPUTC(c, p); 2164b88c807SRodney W. Grimes continue; 2174b88c807SRodney W. Grimes } 218b6748ec2SStefan Farfeleder if (is_ifs == 2 && startword == 1) { 219b6748ec2SStefan Farfeleder /* Only one non-whitespace IFS per word */ 220b6748ec2SStefan Farfeleder startword = 2; 221b6748ec2SStefan Farfeleder if (saveall) 2229d37e157SJilles Tjoelker USTPUTC(c, p); 223b6748ec2SStefan Farfeleder continue; 224b6748ec2SStefan Farfeleder } 225b6748ec2SStefan Farfeleder } 226b6748ec2SStefan Farfeleder 227b6748ec2SStefan Farfeleder if (is_ifs == 0) { 228b6748ec2SStefan Farfeleder /* append this character to the current variable */ 2294b88c807SRodney W. Grimes startword = 0; 230b6748ec2SStefan Farfeleder if (saveall) 231b6748ec2SStefan Farfeleder /* Not just a spare terminator */ 232b6748ec2SStefan Farfeleder saveall++; 2339d37e157SJilles Tjoelker USTPUTC(c, p); 234b6748ec2SStefan Farfeleder continue; 235b6748ec2SStefan Farfeleder } 236b6748ec2SStefan Farfeleder 237b6748ec2SStefan Farfeleder /* end of variable... */ 238b6748ec2SStefan Farfeleder startword = is_ifs; 239b6748ec2SStefan Farfeleder 240b6748ec2SStefan Farfeleder if (ap[1] == NULL) { 241b6748ec2SStefan Farfeleder /* Last variable needs all IFS chars */ 242b6748ec2SStefan Farfeleder saveall++; 2439d37e157SJilles Tjoelker USTPUTC(c, p); 244b6748ec2SStefan Farfeleder continue; 245b6748ec2SStefan Farfeleder } 246b6748ec2SStefan Farfeleder 2474b88c807SRodney W. Grimes STACKSTRNUL(p); 2484b88c807SRodney W. Grimes setvar(*ap, stackblock(), 0); 2494b88c807SRodney W. Grimes ap++; 2504b88c807SRodney W. Grimes STARTSTACKSTR(p); 2514b88c807SRodney W. Grimes } 2524b88c807SRodney W. Grimes STACKSTRNUL(p); 253b6748ec2SStefan Farfeleder 254b6748ec2SStefan Farfeleder /* Remove trailing IFS chars */ 255b6748ec2SStefan Farfeleder for (; stackblock() <= --p; *p = 0) { 256b6748ec2SStefan Farfeleder if (!strchr(ifs, *p)) 257b6748ec2SStefan Farfeleder break; 258b6748ec2SStefan Farfeleder if (strchr(" \t\n", *p)) 259b6748ec2SStefan Farfeleder /* Always remove whitespace */ 260b6748ec2SStefan Farfeleder continue; 261b6748ec2SStefan Farfeleder if (saveall > 1) 262b6748ec2SStefan Farfeleder /* Don't remove non-whitespace unless it was naked */ 263b6748ec2SStefan Farfeleder break; 264b6748ec2SStefan Farfeleder } 2654b88c807SRodney W. Grimes setvar(*ap, stackblock(), 0); 266b6748ec2SStefan Farfeleder 267b6748ec2SStefan Farfeleder /* Set any remaining args to "" */ 2684b88c807SRodney W. Grimes while (*++ap != NULL) 269781bfb5aSJilles Tjoelker setvar(*ap, "", 0); 2704b88c807SRodney W. Grimes return status; 2714b88c807SRodney W. Grimes } 2724b88c807SRodney W. Grimes 2734b88c807SRodney W. Grimes 2744b88c807SRodney W. Grimes 275aa9caaf6SPeter Wemm int 276384aedabSJilles Tjoelker umaskcmd(int argc __unused, char **argv __unused) 277aa9caaf6SPeter Wemm { 278aa9caaf6SPeter Wemm char *ap; 2794b88c807SRodney W. Grimes int mask; 2804b88c807SRodney W. Grimes int i; 281aa9caaf6SPeter Wemm int symbolic_mode = 0; 2824b88c807SRodney W. Grimes 283aa9caaf6SPeter Wemm while ((i = nextopt("S")) != '\0') { 284aa9caaf6SPeter Wemm symbolic_mode = 1; 285aa9caaf6SPeter Wemm } 286aa9caaf6SPeter Wemm 2874b88c807SRodney W. Grimes INTOFF; 2884b88c807SRodney W. Grimes mask = umask(0); 2894b88c807SRodney W. Grimes umask(mask); 2904b88c807SRodney W. Grimes INTON; 291aa9caaf6SPeter Wemm 292aa9caaf6SPeter Wemm if ((ap = *argptr) == NULL) { 293aa9caaf6SPeter Wemm if (symbolic_mode) { 294aa9caaf6SPeter Wemm char u[4], g[4], o[4]; 295aa9caaf6SPeter Wemm 296aa9caaf6SPeter Wemm i = 0; 297aa9caaf6SPeter Wemm if ((mask & S_IRUSR) == 0) 298aa9caaf6SPeter Wemm u[i++] = 'r'; 299aa9caaf6SPeter Wemm if ((mask & S_IWUSR) == 0) 300aa9caaf6SPeter Wemm u[i++] = 'w'; 301aa9caaf6SPeter Wemm if ((mask & S_IXUSR) == 0) 302aa9caaf6SPeter Wemm u[i++] = 'x'; 303aa9caaf6SPeter Wemm u[i] = '\0'; 304aa9caaf6SPeter Wemm 305aa9caaf6SPeter Wemm i = 0; 306aa9caaf6SPeter Wemm if ((mask & S_IRGRP) == 0) 307aa9caaf6SPeter Wemm g[i++] = 'r'; 308aa9caaf6SPeter Wemm if ((mask & S_IWGRP) == 0) 309aa9caaf6SPeter Wemm g[i++] = 'w'; 310aa9caaf6SPeter Wemm if ((mask & S_IXGRP) == 0) 311aa9caaf6SPeter Wemm g[i++] = 'x'; 312aa9caaf6SPeter Wemm g[i] = '\0'; 313aa9caaf6SPeter Wemm 314aa9caaf6SPeter Wemm i = 0; 315aa9caaf6SPeter Wemm if ((mask & S_IROTH) == 0) 316aa9caaf6SPeter Wemm o[i++] = 'r'; 317aa9caaf6SPeter Wemm if ((mask & S_IWOTH) == 0) 318aa9caaf6SPeter Wemm o[i++] = 'w'; 319aa9caaf6SPeter Wemm if ((mask & S_IXOTH) == 0) 320aa9caaf6SPeter Wemm o[i++] = 'x'; 321aa9caaf6SPeter Wemm o[i] = '\0'; 322aa9caaf6SPeter Wemm 323aa9caaf6SPeter Wemm out1fmt("u=%s,g=%s,o=%s\n", u, g, o); 3244b88c807SRodney W. Grimes } else { 325aa9caaf6SPeter Wemm out1fmt("%.4o\n", mask); 326aa9caaf6SPeter Wemm } 327aa9caaf6SPeter Wemm } else { 32858570ac4SJilles Tjoelker if (is_digit(*ap)) { 3294b88c807SRodney W. Grimes mask = 0; 3304b88c807SRodney W. Grimes do { 331aa9caaf6SPeter Wemm if (*ap >= '8' || *ap < '0') 332e4c880afSStefan Farfeleder error("Illegal number: %s", *argptr); 333aa9caaf6SPeter Wemm mask = (mask << 3) + (*ap - '0'); 334aa9caaf6SPeter Wemm } while (*++ap != '\0'); 3354b88c807SRodney W. Grimes umask(mask); 336aa9caaf6SPeter Wemm } else { 337aa9caaf6SPeter Wemm void *set; 338670528cdSStefan Farfeleder INTOFF; 339aa9caaf6SPeter Wemm if ((set = setmode (ap)) == 0) 340aa9caaf6SPeter Wemm error("Illegal number: %s", ap); 341aa9caaf6SPeter Wemm 342aa9caaf6SPeter Wemm mask = getmode (set, ~mask & 0777); 343aa9caaf6SPeter Wemm umask(~mask & 0777); 344a207266eSWarner Losh free(set); 345670528cdSStefan Farfeleder INTON; 346aa9caaf6SPeter Wemm } 3474b88c807SRodney W. Grimes } 3484b88c807SRodney W. Grimes return 0; 3494b88c807SRodney W. Grimes } 3507a2afe64SJoerg Wunsch 351aa9caaf6SPeter Wemm /* 352aa9caaf6SPeter Wemm * ulimit builtin 353aa9caaf6SPeter Wemm * 354aa9caaf6SPeter Wemm * This code, originally by Doug Gwyn, Doug Kingston, Eric Gisin, and 355aa9caaf6SPeter Wemm * Michael Rendell was ripped from pdksh 5.0.8 and hacked for use with 356aa9caaf6SPeter Wemm * ash by J.T. Conklin. 357aa9caaf6SPeter Wemm * 358aa9caaf6SPeter Wemm * Public domain. 359aa9caaf6SPeter Wemm */ 3607a2afe64SJoerg Wunsch 361aa9caaf6SPeter Wemm struct limits { 362aa9caaf6SPeter Wemm const char *name; 36316992ff4SPeter Wemm const char *units; 364aa9caaf6SPeter Wemm int cmd; 365aa9caaf6SPeter Wemm int factor; /* multiply by to get rlim_{cur,max} values */ 366aa9caaf6SPeter Wemm char option; 3677a2afe64SJoerg Wunsch }; 3687a2afe64SJoerg Wunsch 369aa9caaf6SPeter Wemm static const struct limits limits[] = { 370aa9caaf6SPeter Wemm #ifdef RLIMIT_CPU 37116992ff4SPeter Wemm { "cpu time", "seconds", RLIMIT_CPU, 1, 't' }, 372aa9caaf6SPeter Wemm #endif 373aa9caaf6SPeter Wemm #ifdef RLIMIT_FSIZE 37416992ff4SPeter Wemm { "file size", "512-blocks", RLIMIT_FSIZE, 512, 'f' }, 375aa9caaf6SPeter Wemm #endif 376aa9caaf6SPeter Wemm #ifdef RLIMIT_DATA 37716992ff4SPeter Wemm { "data seg size", "kbytes", RLIMIT_DATA, 1024, 'd' }, 378aa9caaf6SPeter Wemm #endif 379aa9caaf6SPeter Wemm #ifdef RLIMIT_STACK 38016992ff4SPeter Wemm { "stack size", "kbytes", RLIMIT_STACK, 1024, 's' }, 381aa9caaf6SPeter Wemm #endif 382aa9caaf6SPeter Wemm #ifdef RLIMIT_CORE 38316992ff4SPeter Wemm { "core file size", "512-blocks", RLIMIT_CORE, 512, 'c' }, 384aa9caaf6SPeter Wemm #endif 385aa9caaf6SPeter Wemm #ifdef RLIMIT_RSS 38616992ff4SPeter Wemm { "max memory size", "kbytes", RLIMIT_RSS, 1024, 'm' }, 387aa9caaf6SPeter Wemm #endif 388aa9caaf6SPeter Wemm #ifdef RLIMIT_MEMLOCK 38916992ff4SPeter Wemm { "locked memory", "kbytes", RLIMIT_MEMLOCK, 1024, 'l' }, 390aa9caaf6SPeter Wemm #endif 391aa9caaf6SPeter Wemm #ifdef RLIMIT_NPROC 39216992ff4SPeter Wemm { "max user processes", (char *)0, RLIMIT_NPROC, 1, 'u' }, 393aa9caaf6SPeter Wemm #endif 394aa9caaf6SPeter Wemm #ifdef RLIMIT_NOFILE 39516992ff4SPeter Wemm { "open files", (char *)0, RLIMIT_NOFILE, 1, 'n' }, 396aa9caaf6SPeter Wemm #endif 397aa9caaf6SPeter Wemm #ifdef RLIMIT_VMEM 39816992ff4SPeter Wemm { "virtual mem size", "kbytes", RLIMIT_VMEM, 1024, 'v' }, 399aa9caaf6SPeter Wemm #endif 400aa9caaf6SPeter Wemm #ifdef RLIMIT_SWAP 40116992ff4SPeter Wemm { "swap limit", "kbytes", RLIMIT_SWAP, 1024, 'w' }, 402aa9caaf6SPeter Wemm #endif 4037cde774dSBrian Feldman #ifdef RLIMIT_SBSIZE 4047cde774dSBrian Feldman { "sbsize", "bytes", RLIMIT_SBSIZE, 1, 'b' }, 4057cde774dSBrian Feldman #endif 406bc093719SEd Schouten #ifdef RLIMIT_NPTS 407bc093719SEd Schouten { "pseudo-terminals", (char *)0, RLIMIT_NPTS, 1, 'p' }, 408bc093719SEd Schouten #endif 40985a0ddfdSKonstantin Belousov #ifdef RLIMIT_KQUEUES 41085a0ddfdSKonstantin Belousov { "kqueues", (char *)0, RLIMIT_KQUEUES, 1, 'k' }, 41185a0ddfdSKonstantin Belousov #endif 41216992ff4SPeter Wemm { (char *) 0, (char *)0, 0, 0, '\0' } 4137a2afe64SJoerg Wunsch }; 4147a2afe64SJoerg Wunsch 4152ef146f1SJilles Tjoelker enum limithow { SOFT = 0x1, HARD = 0x2 }; 4162ef146f1SJilles Tjoelker 4172ef146f1SJilles Tjoelker static void 4182ef146f1SJilles Tjoelker printlimit(enum limithow how, const struct rlimit *limit, 4192ef146f1SJilles Tjoelker const struct limits *l) 4202ef146f1SJilles Tjoelker { 4212ef146f1SJilles Tjoelker rlim_t val = 0; 4222ef146f1SJilles Tjoelker 4232ef146f1SJilles Tjoelker if (how & SOFT) 4242ef146f1SJilles Tjoelker val = limit->rlim_cur; 4252ef146f1SJilles Tjoelker else if (how & HARD) 4262ef146f1SJilles Tjoelker val = limit->rlim_max; 4272ef146f1SJilles Tjoelker if (val == RLIM_INFINITY) 4282ef146f1SJilles Tjoelker out1str("unlimited\n"); 4292ef146f1SJilles Tjoelker else 4302ef146f1SJilles Tjoelker { 4312ef146f1SJilles Tjoelker val /= l->factor; 4322ef146f1SJilles Tjoelker out1fmt("%jd\n", (intmax_t)val); 4332ef146f1SJilles Tjoelker } 4342ef146f1SJilles Tjoelker } 4352ef146f1SJilles Tjoelker 436aa9caaf6SPeter Wemm int 4375134c3f7SWarner Losh ulimitcmd(int argc __unused, char **argv __unused) 438aa9caaf6SPeter Wemm { 4390c1661b7SMaxime Henrion rlim_t val = 0; 4402ef146f1SJilles Tjoelker enum limithow how = SOFT | HARD; 441aa9caaf6SPeter Wemm const struct limits *l; 442aa9caaf6SPeter Wemm int set, all = 0; 443aa9caaf6SPeter Wemm int optc, what; 444aa9caaf6SPeter Wemm struct rlimit limit; 4457a2afe64SJoerg Wunsch 446aa9caaf6SPeter Wemm what = 'f'; 44785a0ddfdSKonstantin Belousov while ((optc = nextopt("HSatfdsmcnuvlbpwk")) != '\0') 448aa9caaf6SPeter Wemm switch (optc) { 4497a2afe64SJoerg Wunsch case 'H': 450aa9caaf6SPeter Wemm how = HARD; 4517a2afe64SJoerg Wunsch break; 4527a2afe64SJoerg Wunsch case 'S': 453aa9caaf6SPeter Wemm how = SOFT; 4547a2afe64SJoerg Wunsch break; 4557a2afe64SJoerg Wunsch case 'a': 456aa9caaf6SPeter Wemm all = 1; 4577a2afe64SJoerg Wunsch break; 458aa9caaf6SPeter Wemm default: 459aa9caaf6SPeter Wemm what = optc; 4607a2afe64SJoerg Wunsch } 4617a2afe64SJoerg Wunsch 462aa9caaf6SPeter Wemm for (l = limits; l->name && l->option != what; l++) 463aa9caaf6SPeter Wemm ; 464aa9caaf6SPeter Wemm if (!l->name) 465abe2dc61STim J. Robbins error("internal error (%c)", what); 4667a2afe64SJoerg Wunsch 467aa9caaf6SPeter Wemm set = *argptr ? 1 : 0; 468aa9caaf6SPeter Wemm if (set) { 469aa9caaf6SPeter Wemm char *p = *argptr; 470aa9caaf6SPeter Wemm 471aa9caaf6SPeter Wemm if (all || argptr[1]) 472abe2dc61STim J. Robbins error("too many arguments"); 473aa9caaf6SPeter Wemm if (strcmp(p, "unlimited") == 0) 4747a2afe64SJoerg Wunsch val = RLIM_INFINITY; 4757a2afe64SJoerg Wunsch else { 4762d70c637SJilles Tjoelker char *end; 4772d70c637SJilles Tjoelker uintmax_t uval; 478aa9caaf6SPeter Wemm 4792d70c637SJilles Tjoelker if (*p < '0' || *p > '9') 480abe2dc61STim J. Robbins error("bad number"); 4812d70c637SJilles Tjoelker errno = 0; 4822d70c637SJilles Tjoelker uval = strtoumax(p, &end, 10); 4832d70c637SJilles Tjoelker if (errno != 0 || *end != '\0') 4842d70c637SJilles Tjoelker error("bad number"); 4852d70c637SJilles Tjoelker if (uval > UINTMAX_MAX / l->factor) 4862d70c637SJilles Tjoelker error("bad number"); 4872d70c637SJilles Tjoelker uval *= l->factor; 4882d70c637SJilles Tjoelker val = (rlim_t)uval; 4892d70c637SJilles Tjoelker if (val < 0 || (uintmax_t)val != uval || 4902d70c637SJilles Tjoelker val == RLIM_INFINITY) 4912d70c637SJilles Tjoelker error("bad number"); 492aa9caaf6SPeter Wemm } 493aa9caaf6SPeter Wemm } 494aa9caaf6SPeter Wemm if (all) { 495aa9caaf6SPeter Wemm for (l = limits; l->name; l++) { 49616992ff4SPeter Wemm char optbuf[40]; 49716992ff4SPeter Wemm if (getrlimit(l->cmd, &limit) < 0) 498abe2dc61STim J. Robbins error("can't get limit: %s", strerror(errno)); 499aa9caaf6SPeter Wemm 50016992ff4SPeter Wemm if (l->units) 50116992ff4SPeter Wemm snprintf(optbuf, sizeof(optbuf), 5024e4e0959SPeter Wemm "(%s, -%c) ", l->units, l->option); 50316992ff4SPeter Wemm else 50416992ff4SPeter Wemm snprintf(optbuf, sizeof(optbuf), 5054e4e0959SPeter Wemm "(-%c) ", l->option); 5064e4e0959SPeter Wemm out1fmt("%-18s %18s ", l->name, optbuf); 5072ef146f1SJilles Tjoelker printlimit(how, &limit, l); 5087a2afe64SJoerg Wunsch } 5097a2afe64SJoerg Wunsch return 0; 5107a2afe64SJoerg Wunsch } 511aa9caaf6SPeter Wemm 51216992ff4SPeter Wemm if (getrlimit(l->cmd, &limit) < 0) 513abe2dc61STim J. Robbins error("can't get limit: %s", strerror(errno)); 514aa9caaf6SPeter Wemm if (set) { 515aa9caaf6SPeter Wemm if (how & SOFT) 516aa9caaf6SPeter Wemm limit.rlim_cur = val; 517aa9caaf6SPeter Wemm if (how & HARD) 518aa9caaf6SPeter Wemm limit.rlim_max = val; 519aa9caaf6SPeter Wemm if (setrlimit(l->cmd, &limit) < 0) 520abe2dc61STim J. Robbins error("bad limit: %s", strerror(errno)); 5212ef146f1SJilles Tjoelker } else 5222ef146f1SJilles Tjoelker printlimit(how, &limit, l); 523aa9caaf6SPeter Wemm return 0; 524aa9caaf6SPeter Wemm } 525