/*********************************************************************** * * * This software is part of the ast package * * Copyright (c) 1982-2009 AT&T Intellectual Property * * and is licensed under the * * Common Public License, Version 1.0 * * by AT&T Intellectual Property * * * * A copy of the License is available at * * http://www.opensource.org/licenses/cpl1.0.txt * * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * * * * Information and Software Systems Research * * AT&T Research * * Florham Park NJ * * * * David Korn * * * ***********************************************************************/ #pragma prototyped /* * ulimit [-HSacdfmnstuv] [limit] * * David Korn * AT&T Labs * */ #include #include #include #include "defs.h" #include "builtins.h" #include "name.h" #include "ulimit.h" #ifndef SH_DICT # define SH_DICT "libshell" #endif #ifdef _no_ulimit int b_ulimit(int argc,char *argv[],void *extra) { NOT_USED(argc); NOT_USED(argv); NOT_USED(extra); errormsg(SH_DICT,ERROR_exit(2),e_nosupport); return(0); } #else static int infof(Opt_t* op, Sfio_t* sp, const char* s, Optdisc_t* dp) { register const Limit_t* tp; for (tp = shtab_limits; tp->option; tp++) { sfprintf(sp, "[%c=%d:%s?The %s", tp->option, tp - shtab_limits + 1, tp->name, tp->description); if(tp->type != LIM_COUNT) sfprintf(sp, " in %ss", e_units[tp->type]); sfprintf(sp, ".]"); } return(1); } #define HARD 2 #define SOFT 4 int b_ulimit(int argc,char *argv[],void *extra) { register char *limit; register int mode=0, n; register unsigned long hit = 0; Shell_t *shp = ((Shbltin_t*)extra)->shp; #ifdef _lib_getrlimit struct rlimit rlp; #endif /* _lib_getrlimit */ const Limit_t* tp; char* conf; int label, unit, nosupport; rlim_t i; char tmp[32]; Optdisc_t disc; memset(&disc, 0, sizeof(disc)); disc.version = OPT_VERSION; disc.infof = infof; opt_info.disc = &disc; while((n = optget(argv,sh_optulimit))) switch(n) { case 'H': mode |= HARD; continue; case 'S': mode |= SOFT; continue; case 'a': hit = ~0; break; default: if(n < 0) hit |= (1L<<(-(n+1))); else errormsg(SH_DICT,2, e_notimp, opt_info.name); break; case ':': errormsg(SH_DICT,2, "%s", opt_info.arg); break; case '?': errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg); break; } opt_info.disc = 0; /* default to -f */ limit = argv[opt_info.index]; if(hit==0) for(n=0; shtab_limits[n].option; n++) if(shtab_limits[n].index == RLIMIT_FSIZE) { hit |= (1L<opt_info.index+1) errormsg(SH_DICT,ERROR_usage(2),optusage((char*)0)); if(mode==0) mode = (HARD|SOFT); for(tp = shtab_limits; tp->option && hit; tp++,hit>>=1) { if(!(hit&1)) continue; nosupport = (n = tp->index) == RLIMIT_UNKNOWN; unit = shtab_units[tp->type]; if(limit) { if(shp->subshell && !shp->subshare) sh_subfork(); if(strcmp(limit,e_unlimited)==0) i = INFINITY; else { char *last; if((i=sh_strnum(limit,&last,2))==INFINITY || *last) errormsg(SH_DICT,ERROR_system(1),e_number,limit); i *= unit; } if(nosupport) errormsg(SH_DICT,ERROR_system(1),e_readonly,tp->name); else { #ifdef _lib_getrlimit if(getrlimit(n,&rlp) <0) errormsg(SH_DICT,ERROR_system(1),e_number,limit); if(mode&HARD) rlp.rlim_max = i; if(mode&SOFT) rlp.rlim_cur = i; if(setrlimit(n,&rlp) <0) errormsg(SH_DICT,ERROR_system(1),e_overlimit,limit); #else if((i=vlimit(n,i)) < 0) errormsg(SH_DICT,ERROR_system(1),e_number,limit); #endif /* _lib_getrlimit */ } } else { if(!nosupport) { #ifdef _lib_getrlimit if(getrlimit(n,&rlp) <0) errormsg(SH_DICT,ERROR_system(1),e_number,limit); if(mode&HARD) i = rlp.rlim_max; if(mode&SOFT) i = rlp.rlim_cur; #else # ifdef _lib_ulimit n--; # endif /* _lib_ulimit */ i = -1; if((i=vlimit(n,i)) < 0) errormsg(SH_DICT,ERROR_system(1),e_number,limit); #endif /* _lib_getrlimit */ } if(label) { if(tp->type != LIM_COUNT) sfsprintf(tmp,sizeof(tmp),"%s (%ss)", tp->description, e_units[tp->type]); else sfsprintf(tmp,sizeof(tmp),"%s", tp->name); sfprintf(sfstdout,"%-30s (-%c) ",tmp,tp->option); } if(nosupport) { if(!tp->conf || !*(conf = astconf(tp->conf, NiL, NiL))) conf = (char*)e_nosupport; sfputr(sfstdout,conf,'\n'); } else if(i!=INFINITY) { i += (unit-1); sfprintf(sfstdout,"%I*d\n",sizeof(i),i/unit); } else sfputr(sfstdout,e_unlimited,'\n'); } } return(0); } #endif /* _no_ulimit */