#include <u.h>#include <sys/time.h>#include <sys/stat.h>#include <sys/resource.h>#include <errno.h>#include <fcntl.h>#include <libc.h>#include "rc.h"#include "exec.h"#include "io.h"#include "fns.h"#include "getflags.h"extern char **mkenv(void);extern char **mkargv(word*);extern int mapfd(int); char pathsep = ':'; static char *eargs = "cdflmnstuv";static int rlx[] = { RLIMIT_CORE, RLIMIT_DATA, RLIMIT_FSIZE,#ifdef RLIMIT_MEMLOCK RLIMIT_MEMLOCK,#else 0,#endif#ifdef RLIMIT_RSS RLIMIT_RSS,#else 0,#endif RLIMIT_NOFILE, RLIMIT_STACK, RLIMIT_CPU,#ifdef RLIMIT_NPROC RLIMIT_NPROC,#else 0,#endif#ifdef RLIMIT_RSS RLIMIT_RSS,#else 0,#endif}; static voideusage(void){ fprint(mapfd(2), "usage: ulimit [-SHa%s [limit]]\n", eargs);} #define Notset -4#define Unlimited -3#define Hard -2#define Soft -1 voidexeculimit(void){ int fd, n, argc, sethard, setsoft, limit; int flag[256]; char **argv, **oargv, *p; char *argv0; struct rlimit rl; argv0 = nil; setstatus(""); oargv = mkargv(runq->argv->words); argv = oargv+1; for(argc=0; argv[argc]; argc++) ; memset(flag, 0, sizeof flag); ARGBEGIN{ default: if(strchr(eargs, ARGC()) == nil){ eusage(); return; } case 'S': case 'H': case 'a': flag[ARGC()] = 1; break; }ARGEND if(argc > 1){ eusage(); goto out; } fd = mapfd(1); sethard = 1; setsoft = 1; if(flag['S'] && flag['H']) ; else if(flag['S']) sethard = 0; else if(flag['H']) setsoft = 0; limit = Notset; if(argc>0){ if(strcmp(argv[0], "unlimited") == 0) limit = Unlimited; else if(strcmp(argv[0], "hard") == 0) limit = Hard; else if(strcmp(argv[0], "soft") == 0) limit = Soft; else if((limit = strtol(argv[0], &p, 0)) < 0 || *p != 0){ eusage(); goto out; } } if(flag['a']){ for(p=eargs; *p; p++){ getrlimit(rlx[p-eargs], &rl); n = flag['H'] ? rl.rlim_max : rl.rlim_cur; if(n == -1) fprint(fd, "ulimit -%c unlimited\n", *p); else fprint(fd, "ulimit -%c %d\n", *p, n); } goto out; } for(p=eargs; *p; p++){ if(flag[(uchar)*p]){ n = 0; getrlimit(rlx[p-eargs], &rl); switch(limit){ case Notset: n = flag['H'] ? rl.rlim_max : rl.rlim_cur; if(n == -1) fprint(fd, "ulimit -%c unlimited\n", *p); else fprint(fd, "ulimit -%c %d\n", *p, n); break; case Hard: n = rl.rlim_max; goto set; case Soft: n = rl.rlim_cur; goto set; case Unlimited: n = -1; goto set; default: n = limit; set: if(setsoft) rl.rlim_cur = n; if(sethard) rl.rlim_max = n; if(setrlimit(rlx[p-eargs], &rl) < 0) fprint(mapfd(2), "setrlimit: %r\n"); } } } out: free(oargv); poplist(); flush(err);} voidexecumask(void){ int n, argc; char **argv, **oargv, *p; char *argv0; argv0 = nil; setstatus(""); oargv = mkargv(runq->argv->words); argv = oargv+1; for(argc=0; argv[argc]; argc++) ; ARGBEGIN{ default: usage: fprint(mapfd(2), "usage: umask [mode]\n"); goto out; }ARGEND if(argc > 1) goto usage; if(argc == 1){ n = strtol(argv[0], &p, 8); if(*p != 0 || p == argv[0]) goto usage; umask(n); goto out; } n = umask(0); umask(n); if(n < 0){ fprint(mapfd(2), "umask: %r\n"); goto out; } fprint(mapfd(1), "umask %03o\n", n); out: free(oargv); poplist(); flush(err);} /* * Cope with non-blocking read. */longreadnb(int fd, char *buf, long cnt){ int n, didreset; int flgs; didreset = 0;again: n = read(fd, buf, cnt); if(n == -1) if(errno == EAGAIN){ if(!didreset){ if((flgs = fcntl(fd, F_GETFL, 0)) == -1) return -1; flgs &= ~O_NONBLOCK; if(fcntl(fd, F_SETFL, flgs) == -1) return -1; didreset = 1; } goto again; } return n;}void Updenv(void){}void Execute(word *args, word *path){ char **argv=mkargv(args); char **env=mkenv(); char file[1024]; int nc; Updenv(); for(;path;path=path->next){ nc=strlen(path->word); if(nc<1024){ strcpy(file, path->word); if(file[0]){ strcat(file, "/"); nc++; } if(nc+strlen(argv[1])<1024){ strcat(file, argv[1]); execve(file, argv+1, env); } else werrstr("command name too long"); } } rerrstr(file, sizeof file); pfmt(err, "%s: %s\n", argv[1], file); efree((char *)argv);}int Executable(char *file){ Dir *statbuf; int ret; statbuf = dirstat(file); if(statbuf == nil) return 0; ret = ((statbuf->mode&0111)!=0 && (statbuf->mode&DMDIR)==0); free(statbuf); return ret;}
#include <u.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/resource.h>
#include <errno.h>
#include <fcntl.h>
#include <libc.h>
#include "rc.h"
#include "exec.h"
#include "io.h"
#include "fns.h"
#include "getflags.h"
extern char **mkenv(void);
extern char **mkargv(word*);
extern int mapfd(int);
char pathsep = ':';
static char *eargs = "cdflmnstuv";
static int rlx[] = {
RLIMIT_CORE,
RLIMIT_DATA,
RLIMIT_FSIZE,
#ifdef RLIMIT_MEMLOCK
RLIMIT_MEMLOCK,
#else
0,
#endif
#ifdef RLIMIT_RSS
RLIMIT_RSS,
#else
0,
#endif
RLIMIT_NOFILE,
RLIMIT_STACK,
RLIMIT_CPU,
#ifdef RLIMIT_NPROC
RLIMIT_NPROC,
#else
0,
#endif
#ifdef RLIMIT_RSS
RLIMIT_RSS,
#else
0,
#endif
};
static void
eusage(void)
{
fprint(mapfd(2), "usage: ulimit [-SHa%s [limit]]\n", eargs);
}
#define Notset -4
#define Unlimited -3
#define Hard -2
#define Soft -1
void
execulimit(void)
{
int fd, n, argc, sethard, setsoft, limit;
int flag[256];
char **argv, **oargv, *p;
char *argv0;
struct rlimit rl;
argv0 = nil;
setstatus("");
oargv = mkargv(runq->argv->words);
argv = oargv+1;
for(argc=0; argv[argc]; argc++)
;
memset(flag, 0, sizeof flag);
ARGBEGIN{
default:
if(strchr(eargs, ARGC()) == nil){
eusage();
return;
}
case 'S':
case 'H':
case 'a':
flag[ARGC()] = 1;
break;
}ARGEND
if(argc > 1){
eusage();
goto out;
}
fd = mapfd(1);
sethard = 1;
setsoft = 1;
if(flag['S'] && flag['H'])
;
else if(flag['S'])
sethard = 0;
else if(flag['H'])
setsoft = 0;
limit = Notset;
if(argc>0){
if(strcmp(argv[0], "unlimited") == 0)
limit = Unlimited;
else if(strcmp(argv[0], "hard") == 0)
limit = Hard;
else if(strcmp(argv[0], "soft") == 0)
limit = Soft;
else if((limit = strtol(argv[0], &p, 0)) < 0 || *p != 0){
eusage();
goto out;
}
}
if(flag['a']){
for(p=eargs; *p; p++){
getrlimit(rlx[p-eargs], &rl);
n = flag['H'] ? rl.rlim_max : rl.rlim_cur;
if(n == -1)
fprint(fd, "ulimit -%c unlimited\n", *p);
else
fprint(fd, "ulimit -%c %d\n", *p, n);
}
goto out;
}
for(p=eargs; *p; p++){
if(flag[(uchar)*p]){
n = 0;
getrlimit(rlx[p-eargs], &rl);
switch(limit){
case Notset:
n = flag['H'] ? rl.rlim_max : rl.rlim_cur;
if(n == -1)
fprint(fd, "ulimit -%c unlimited\n", *p);
else
fprint(fd, "ulimit -%c %d\n", *p, n);
break;
case Hard:
n = rl.rlim_max;
goto set;
case Soft:
n = rl.rlim_cur;
goto set;
case Unlimited:
n = -1;
goto set;
default:
n = limit;
set:
if(setsoft)
rl.rlim_cur = n;
if(sethard)
rl.rlim_max = n;
if(setrlimit(rlx[p-eargs], &rl) < 0)
fprint(mapfd(2), "setrlimit: %r\n");
}
}
}
out:
free(oargv);
poplist();
flush(err);
}
void
execumask(void)
{
int n, argc;
char **argv, **oargv, *p;
char *argv0;
argv0 = nil;
setstatus("");
oargv = mkargv(runq->argv->words);
argv = oargv+1;
for(argc=0; argv[argc]; argc++)
;
ARGBEGIN{
default:
usage:
fprint(mapfd(2), "usage: umask [mode]\n");
goto out;
}ARGEND
if(argc > 1)
goto usage;
if(argc == 1){
n = strtol(argv[0], &p, 8);
if(*p != 0 || p == argv[0])
goto usage;
umask(n);
goto out;
}
n = umask(0);
umask(n);
if(n < 0){
fprint(mapfd(2), "umask: %r\n");
goto out;
}
fprint(mapfd(1), "umask %03o\n", n);
out:
free(oargv);
poplist();
flush(err);
}
/*
* Cope with non-blocking read.
*/
long
readnb(int fd, char *buf, long cnt)
{
int n, didreset;
int flgs;
didreset = 0;
again:
n = read(fd, buf, cnt);
if(n == -1)
if(errno == EAGAIN){
if(!didreset){
if((flgs = fcntl(fd, F_GETFL, 0)) == -1)
return -1;
flgs &= ~O_NONBLOCK;
if(fcntl(fd, F_SETFL, flgs) == -1)
return -1;
didreset = 1;
}
goto again;
}
return n;
}
void Updenv(void){}
void Execute(word *args, word *path)
{
char **argv=mkargv(args);
char **env=mkenv();
char file[1024];
int nc;
Updenv();
for(;path;path=path->next){
nc=strlen(path->word);
if(nc<1024){
strcpy(file, path->word);
if(file[0]){
strcat(file, "/");
nc++;
}
if(nc+strlen(argv[1])<1024){
strcat(file, argv[1]);
execve(file, argv+1, env);
}
else werrstr("command name too long");
}
}
rerrstr(file, sizeof file);
pfmt(err, "%s: %s\n", argv[1], file);
efree((char *)argv);
}
int Executable(char *file)
{
Dir *statbuf;
int ret;
statbuf = dirstat(file);
if(statbuf == nil) return 0;
ret = ((statbuf->mode&0111)!=0 && (statbuf->mode&DMDIR)==0);
free(statbuf);
return ret;
}