14887Schin /***********************************************************************
24887Schin * *
34887Schin * This software is part of the ast package *
4*12068SRoger.Faulkner@Oracle.COM * Copyright (c) 1982-2010 AT&T Intellectual Property *
54887Schin * and is licensed under the *
64887Schin * Common Public License, Version 1.0 *
78462SApril.Chin@Sun.COM * by AT&T Intellectual Property *
84887Schin * *
94887Schin * A copy of the License is available at *
104887Schin * http://www.opensource.org/licenses/cpl1.0.txt *
114887Schin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
124887Schin * *
134887Schin * Information and Software Systems Research *
144887Schin * AT&T Research *
154887Schin * Florham Park NJ *
164887Schin * *
174887Schin * David Korn <dgk@research.att.com> *
184887Schin * *
194887Schin ***********************************************************************/
204887Schin #pragma prototyped
214887Schin /*
224887Schin * ulimit [-HSacdfmnstuv] [limit]
234887Schin *
244887Schin * David Korn
254887Schin * AT&T Labs
264887Schin *
274887Schin */
284887Schin
294887Schin #include <ast.h>
304887Schin #include <sfio.h>
314887Schin #include <error.h>
3210898Sroland.mainz@nrubsig.org #include "defs.h"
334887Schin #include "builtins.h"
344887Schin #include "name.h"
354887Schin #include "ulimit.h"
364887Schin #ifndef SH_DICT
374887Schin # define SH_DICT "libshell"
384887Schin #endif
394887Schin
404887Schin #ifdef _no_ulimit
b_ulimit(int argc,char * argv[],void * extra)414887Schin int b_ulimit(int argc,char *argv[],void *extra)
424887Schin {
434887Schin NOT_USED(argc);
444887Schin NOT_USED(argv);
454887Schin NOT_USED(extra);
464887Schin errormsg(SH_DICT,ERROR_exit(2),e_nosupport);
474887Schin return(0);
484887Schin }
494887Schin #else
504887Schin
infof(Opt_t * op,Sfio_t * sp,const char * s,Optdisc_t * dp)514887Schin static int infof(Opt_t* op, Sfio_t* sp, const char* s, Optdisc_t* dp)
524887Schin {
534887Schin register const Limit_t* tp;
544887Schin
554887Schin for (tp = shtab_limits; tp->option; tp++)
564887Schin {
574887Schin sfprintf(sp, "[%c=%d:%s?The %s", tp->option, tp - shtab_limits + 1, tp->name, tp->description);
584887Schin if(tp->type != LIM_COUNT)
594887Schin sfprintf(sp, " in %ss", e_units[tp->type]);
604887Schin sfprintf(sp, ".]");
614887Schin }
624887Schin return(1);
634887Schin }
644887Schin
654887Schin #define HARD 2
664887Schin #define SOFT 4
674887Schin
b_ulimit(int argc,char * argv[],void * extra)684887Schin int b_ulimit(int argc,char *argv[],void *extra)
694887Schin {
704887Schin register char *limit;
714887Schin register int mode=0, n;
724887Schin register unsigned long hit = 0;
738462SApril.Chin@Sun.COM Shell_t *shp = ((Shbltin_t*)extra)->shp;
744887Schin #ifdef _lib_getrlimit
754887Schin struct rlimit rlp;
764887Schin #endif /* _lib_getrlimit */
774887Schin const Limit_t* tp;
784887Schin char* conf;
798462SApril.Chin@Sun.COM int label, unit, nosupport;
804887Schin rlim_t i;
814887Schin char tmp[32];
824887Schin Optdisc_t disc;
834887Schin memset(&disc, 0, sizeof(disc));
844887Schin disc.version = OPT_VERSION;
854887Schin disc.infof = infof;
864887Schin opt_info.disc = &disc;
874887Schin while((n = optget(argv,sh_optulimit))) switch(n)
884887Schin {
894887Schin case 'H':
904887Schin mode |= HARD;
914887Schin continue;
924887Schin case 'S':
934887Schin mode |= SOFT;
944887Schin continue;
954887Schin case 'a':
964887Schin hit = ~0;
974887Schin break;
984887Schin default:
994887Schin if(n < 0)
1004887Schin hit |= (1L<<(-(n+1)));
1014887Schin else
1024887Schin errormsg(SH_DICT,2, e_notimp, opt_info.name);
1034887Schin break;
1044887Schin case ':':
1054887Schin errormsg(SH_DICT,2, "%s", opt_info.arg);
1064887Schin break;
1074887Schin case '?':
1084887Schin errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg);
1094887Schin break;
1104887Schin }
1114887Schin opt_info.disc = 0;
1128462SApril.Chin@Sun.COM /* default to -f */
1134887Schin limit = argv[opt_info.index];
1148462SApril.Chin@Sun.COM if(hit==0)
1154887Schin for(n=0; shtab_limits[n].option; n++)
1164887Schin if(shtab_limits[n].index == RLIMIT_FSIZE)
1174887Schin {
1184887Schin hit |= (1L<<n);
1194887Schin break;
1204887Schin }
1214887Schin /* only one option at a time for setting */
1224887Schin label = (hit&(hit-1));
1234887Schin if(error_info.errors || (limit && label) || argc>opt_info.index+1)
1244887Schin errormsg(SH_DICT,ERROR_usage(2),optusage((char*)0));
1254887Schin if(mode==0)
1264887Schin mode = (HARD|SOFT);
1274887Schin for(tp = shtab_limits; tp->option && hit; tp++,hit>>=1)
1284887Schin {
1294887Schin if(!(hit&1))
1304887Schin continue;
1314887Schin nosupport = (n = tp->index) == RLIMIT_UNKNOWN;
1324887Schin unit = shtab_units[tp->type];
1334887Schin if(limit)
1344887Schin {
13510898Sroland.mainz@nrubsig.org if(shp->subshell && !shp->subshare)
1364887Schin sh_subfork();
1374887Schin if(strcmp(limit,e_unlimited)==0)
1384887Schin i = INFINITY;
1394887Schin else
1404887Schin {
1414887Schin char *last;
1424887Schin if((i=sh_strnum(limit,&last,2))==INFINITY || *last)
1434887Schin errormsg(SH_DICT,ERROR_system(1),e_number,limit);
1444887Schin i *= unit;
1454887Schin }
1464887Schin if(nosupport)
1474887Schin errormsg(SH_DICT,ERROR_system(1),e_readonly,tp->name);
1484887Schin else
1494887Schin {
1504887Schin #ifdef _lib_getrlimit
1514887Schin if(getrlimit(n,&rlp) <0)
1524887Schin errormsg(SH_DICT,ERROR_system(1),e_number,limit);
1534887Schin if(mode&HARD)
1544887Schin rlp.rlim_max = i;
1554887Schin if(mode&SOFT)
1564887Schin rlp.rlim_cur = i;
1574887Schin if(setrlimit(n,&rlp) <0)
1584887Schin errormsg(SH_DICT,ERROR_system(1),e_overlimit,limit);
1594887Schin #else
1604887Schin if((i=vlimit(n,i)) < 0)
1614887Schin errormsg(SH_DICT,ERROR_system(1),e_number,limit);
1624887Schin #endif /* _lib_getrlimit */
1634887Schin }
1644887Schin }
1654887Schin else
1664887Schin {
1674887Schin if(!nosupport)
1684887Schin {
1694887Schin #ifdef _lib_getrlimit
1704887Schin if(getrlimit(n,&rlp) <0)
1714887Schin errormsg(SH_DICT,ERROR_system(1),e_number,limit);
1724887Schin if(mode&HARD)
1734887Schin i = rlp.rlim_max;
1744887Schin if(mode&SOFT)
1754887Schin i = rlp.rlim_cur;
1764887Schin #else
1774887Schin # ifdef _lib_ulimit
1784887Schin n--;
1794887Schin # endif /* _lib_ulimit */
1804887Schin i = -1;
1814887Schin if((i=vlimit(n,i)) < 0)
1824887Schin errormsg(SH_DICT,ERROR_system(1),e_number,limit);
1834887Schin #endif /* _lib_getrlimit */
1844887Schin }
1854887Schin if(label)
1864887Schin {
1874887Schin if(tp->type != LIM_COUNT)
1884887Schin sfsprintf(tmp,sizeof(tmp),"%s (%ss)", tp->description, e_units[tp->type]);
1894887Schin else
1904887Schin sfsprintf(tmp,sizeof(tmp),"%s", tp->name);
1914887Schin sfprintf(sfstdout,"%-30s (-%c) ",tmp,tp->option);
1924887Schin }
1934887Schin if(nosupport)
1944887Schin {
1954887Schin if(!tp->conf || !*(conf = astconf(tp->conf, NiL, NiL)))
1964887Schin conf = (char*)e_nosupport;
1974887Schin sfputr(sfstdout,conf,'\n');
1984887Schin }
1998462SApril.Chin@Sun.COM else if(i!=INFINITY)
2004887Schin {
2018462SApril.Chin@Sun.COM i += (unit-1);
2024887Schin sfprintf(sfstdout,"%I*d\n",sizeof(i),i/unit);
2034887Schin }
2044887Schin else
2054887Schin sfputr(sfstdout,e_unlimited,'\n');
2064887Schin }
2074887Schin }
2084887Schin return(0);
2094887Schin }
2104887Schin #endif /* _no_ulimit */
211