123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128 |
- /*
- The MON instruction
- */
- /* $Id$ */
- #include "sysidf.h"
- #include "log.h"
- #include "alloc.h"
- #include "shadow.h"
- #include <sys/types.h>
- #include <sys/stat.h>
- #if __STDC__
- #include <time.h>
- #endif
- #include <sys/times.h>
- extern int errno; /* UNIX error number */
- extern int running; /* from main.c */
- extern int fd_limit; /* from io.c */
- #define good_fd(fd) (fd < fd_limit ? 1 : (errno = 9 /* EBADF */, 0))
- #ifdef BSD_X /* from system.h */
- #include <sys/timeb.h>
- #endif /* BSD_X */
- #ifdef SYS_V
- struct timeb { /* non-existing; we use an ad-hoc definition */
- long time;
- unsigned short millitm;
- short timezone, dstflag;
- };
- #endif /* SYS_V */
- #ifdef BSD4_2 /* from system.h */
- #include <sys/time.h>
- #endif /* BSD4_2 */
- #ifdef SYS_V
- #include <sys/errno.h>
- #undef ERANGE /* collision with trap.h */
- #include <fcntl.h>
- #include <time.h>
- #endif /* SYS_V */
- #include <em_abs.h>
- #include "logging.h"
- #include "global.h"
- #include "trap.h"
- #include "warn.h"
- #include "mem.h"
- #define INPUT 0
- #define OUTPUT 1
- #define DUPMASK 0x40
- extern long lseek();
- #ifdef SYS_V
- extern unsigned int alarm();
- extern long time();
- extern void sync();
- #endif /* SYS_V */
- #define INT2SIZE max(wsize, 2L)
- #define INT4SIZE max(wsize, 4L)
- #define pop_int() ((int) swpop())
- #define pop_int2() ((int) spop(INT2SIZE))
- #define pop_int4() (spop(INT4SIZE))
- #define pop_intp() ((int) spop(psize))
- #define pop_uns2() ((unsigned int) upop(INT2SIZE))
- #define pop_unsp() ((unsigned int) upop(psize))
- #define pop_ptr() (dppop())
- #define push_int(a) (wpush((long)(a)))
- #define push_i2(a) (npush((long)(a), INT2SIZE))
- #define push_i4(a) (npush((long)(a), INT4SIZE))
- #define push_unsp(a) (npush((long)(a), psize))
- #define push_err() { push_int(errno); push_int(errno); }
- /************************************************************************
- * Monitor calls. *
- * *
- * The instruction "MON" expects a wsized integer on top of *
- * top of the stack, which identifies the call. Often there *
- * are also parameters following this number. The parameters *
- * were stacked in reverse order (C convention). *
- * The possible parameter types are : *
- * *
- * 1) int : integer of wordsize *
- * 2) int2: integer with size max(2, wordsize) *
- * 3) int4: integer with size max(4, wordsize) *
- * 4) intp: integer with size of a pointer *
- * 5) uns2: unsigned integer with size max(2, wordsize) *
- * 6) unsp: unsigned integer with size of a pointer *
- * 7) ptr : pointer into data space *
- * *
- * After the call has been executed, a return code is present *
- * on top of the stack. If this return code equals zero, the call *
- * succeeded and the results of the call can be found right *
- * after the return code. A non zero return code indicates a *
- * failure. In this case no results are available and the return *
- * code has been pushed twice. *
- * *
- * Monitor calls such as "ioctl", "stat", "ftime", etc. work *
- * with a private buffer to be filled by the call. The fields *
- * of the buffer are written to EM-memory separately, possibly *
- * with some of the fields aligned. To this end a number of *
- * transport routines are assembled in monstruct.[ch]. *
- * *
- * The EM report specifies a list of UNIX Version 7 -like system *
- * calls, not full access to the system calls on the underlying *
- * machine. Therefore an attempt has been made to use or emulate *
- * the Version 7 system calls on the various machines. A number *
- * of 4.1 BSD specific parameters have also been implemented. *
- * *
- ************************************************************************/
- PRIVATE size buf_cnt[5]; /* Current sizes of the buffers */
- PRIVATE char *buf[5]; /* Pointers to the buffers */
- PRIVATE check_buf();
- PRIVATE int savestr();
- PRIVATE int vec();
- moncall()
- {
- int n; /* number actually read/written */
- int status; /* status for wait-call */
- int flag; /* various flag parameters */
- int mode; /* various mode parameters */
- int oldmask; /* for umask call */
- int whence; /* parameter for lseek */
- int address; /* address parameter typed int2 */
- int owner; /* owner parameter typed int2 */
- int group; /* group parameter typed int2 */
- int pid; /* pid parameter typed int2 */
- int ppid; /* parent process pid */
- long off; /* offset parameter */
- int pfds[2]; /* pipe file descriptors */
- long tm; /* for stime call */
- long actime, modtime; /* for utime */
- int incr; /* for nice call */
- int fd, fdnew; /* file descriptors */
- int groupid; /* group id */
- int userid; /* user id */
- int sig; /* killing signal */
- ptr dsp1, dsp2, dsp3; /* Data Space Pointers */
- int nbytes; /* number to be read/written */
- unsigned int seconds; /* for alarm call */
- int trap_no; /* for sigtrp; trap number */
- int old_trap_no; /* for sigtrp; old trap number */
- int sig_no; /* for sigtrp; signal number */
- int request; /* ioctl and ptrace request */
- char **envvec; /* environment vector (exec) */
- char **argvec; /* argument vector (exec) */
- struct stat st_buf; /* private stat buffer */
- struct tms tm_buf; /* private tms buffer */
- struct timeb tb_buf; /* private timeb buffer */
- #ifdef BSD4_2 /* from system.h */
- struct timeval tv; /* private timeval buffer */
- #endif /* BSD4_2 */
- #ifdef SYS_V /* from system.h */
- struct {time_t x, y;} utimbuf; /* private utime buffer */
- #else /* SYS_V */
- time_t utimbuf[2]; /* private utime buffer */
- #endif /* !SYS_V */
- char *cp;
- int nr;
- ptr addr;
- int rc;
- switch (pop_int()) {
- case 1: /* Exit */
- #ifdef LOGGING
- ES_def =
- ((st_sh(SP) == UNDEFINED)
- || (st_sh(SP + wsize-1) == UNDEFINED)) ?
- UNDEFINED : DEFINED;
- #else
- ES_def = DEFINED;
- #endif /* LOGGING */
- ES = pop_int();
- running = 0; /* stop the machine */
- LOG(("@m9 Exit: ES = %ld", ES));
- break;
- case 2: /* Fork */
- ppid = getpid();
- if ((pid = fork()) == 0) {
- /* Child */
- init_ofiles(0); /* Reinitialize */
- push_int(ppid); /* Pid of parent */
- push_int(1); /* Flag = 1 for child */
- push_int(0);
- LOG(("@m9 Fork: in child, ppid = %d", ppid));
- }
- else if (pid > 0) { /* Parent */
- incr_mess_id(); /* Incr. id for next child */
- push_int(pid); /* Pid of child */
- push_int(0); /* Flag = 0 for parent */
- push_int(0);
- LOG(("@m9 Fork: in parent, cpid = %d", pid));
- }
- else {
- /* fork call failed */
- push_err();
- LOG(("@m4 Fork: failed, pid = %d, errno = %d",
- pid, errno));
- }
- break;
- case 3: /* Read */
- fd = pop_int();
- dsp1 = pop_ptr();
- nbytes = pop_intp();
- if (!good_fd(fd))
- goto read_error;
- if (nbytes < 0) {
- errno = 22; /* EINVAL */
- goto read_error;
- }
- check_buf(0, (size)nbytes);
- if ((n = read(fd, buf[0], nbytes)) == -1)
- goto read_error;
- #ifdef LOGGING
- if (check_log("@m6")) {
- register int i;
-
- for (i = 0; i < n; i++) {
- LOG(("@m6 Read: char = '%c'", *(buf[0] + i)));
- }
- }
- #endif /* LOGGING */
- if (in_gda(dsp1) && !in_gda(dsp1 + (n-1))) {
- efault(WRGDAH);
- goto read_error;
- }
- if (!is_in_mem(dsp1, n)) {
- efault(WRUMEM);
- goto read_error;
- }
- for ( nr = n, cp = buf[0], addr = dsp1;
- nr;
- nr--, addr++, cp++
- ) {
- if (in_stack(addr)) {
- ch_st_prot(addr);
- stack_loc(addr) = *cp;
- st_int(addr);
- }
- else {
- ch_dt_prot(addr);
- data_loc(addr) = *cp;
- dt_int(addr);
- }
- }
- push_unsp(n);
- push_int(0);
- LOG(("@m9 Read: succeeded, n = %d", n));
- break;
- read_error:
- push_err();
- LOG(("@m4 Read: failed, n = %d, errno = %d", n, errno));
- break;
- case 4: /* Write */
- fd = pop_int();
- dsp1 = pop_ptr();
- nbytes = pop_intp();
- if (!good_fd(fd))
- goto write_error;
- if (nbytes < 0) {
- errno = 22; /* EINVAL */
- goto read_error;
- }
- if (in_gda(dsp1) && !in_gda(dsp1 + (nbytes-1))) {
- efault(WWGDAH);
- goto write_error;
- }
- if (!is_in_mem(dsp1, nbytes)) {
- efault(WWUMEM);
- goto write_error;
- }
- #ifdef LOGGING
- for (addr = dsp1; addr < dsp1 + nbytes; addr++) {
- if (mem_sh(addr) == UNDEFINED) {
- warning(in_stack(addr) ? WWLUNDEF : WWGUNDEF);
- }
- }
- #endif /* LOGGING */
- check_buf(0, (size)nbytes);
- for ( nr = nbytes, addr = dsp1, cp = buf[0];
- nr;
- nr--, addr++, cp++
- ) {
- *cp = mem_loc(addr);
- }
- #ifdef LOGGING
- if (check_log("@m6")) {
- register int i;
-
- for (i = 0; i < nbytes; i++) {
- LOG(("@m6 write: char = '%c'", *(buf[0] + i)));
- }
- }
- #endif /* LOGGING */
- if ((n = write(fd, buf[0], nbytes)) == -1)
- goto write_error;
- push_unsp(n);
- push_int(0);
- LOG(("@m9 Write: succeeded, n = %d", n));
- break;
- write_error:
- push_err();
- LOG(("@m4 Write: failed, n = %d, nbytes = %d, errno = %d",
- n, nbytes, errno));
- break;
- case 5: /* Open */
- dsp1 = pop_ptr();
- flag = pop_int();
- if (!savestr(0, dsp1) || (fd = open(buf[0], flag)) == -1) {
- push_err();
- LOG(("@m4 Open: failed, file = %lu, flag = %d, fd = %d, errno = %d",
- dsp1, flag, fd, errno));
- }
- else {
- push_int(fd);
- push_int(0);
- LOG(("@m9 Open: succeeded, file = %lu, flag = %d, fd = %d",
- dsp1, flag, fd));
- }
- break;
- case 6: /* Close */
- fd = pop_int();
- if (!good_fd(fd) || close(fd) == -1) {
- push_err();
- LOG(("@m4 Close: failed, fd = %d, errno = %d",
- fd, errno));
- }
- else {
- push_int(0);
- LOG(("@m9 Close: succeeded"));
- }
- break;
- case 7: /* Wait */
- if ((pid = wait(&status)) == -1) {
- push_err();
- LOG(("@m4 Wait: failed, status = %d, errno = %d",
- status, errno));
- }
- else {
- push_i2(pid);
- push_i2(status);
- push_int(0);
- LOG(("@m9 Wait: succeeded, status = %d, pid = %d",
- status, pid));
- }
- break;
- case 8: /* Creat */
- dsp1 = pop_ptr();
- flag = pop_int();
- if (!savestr(0, dsp1) || (fd = creat(buf[0], flag)) == -1) {
- push_err();
- LOG(("@m4 Creat: failed, dsp1 = %lu, flag = %d, errno = %d",
- dsp1, flag, errno));
- }
- else {
- push_int(fd);
- push_int(0);
- LOG(("@m9 Creat: succeeded, fd = %d", fd));
- }
- break;
- case 9: /* Link */
- dsp1 = pop_ptr();
- dsp2 = pop_ptr();
- if ( !savestr(0, dsp1)
- || !savestr(1, dsp2)
- || link(buf[0], buf[1]) == -1
- ) {
- push_err();
- LOG(("@m4 Link: failed, dsp1 = %lu, dsp2 = %lu, errno = %d",
- dsp1, dsp2, errno));
- }
- else {
- push_int(0);
- LOG(("@m9 Link: succeeded, dsp1 = %lu, dsp2 = %lu",
- dsp1, dsp2));
- }
- break;
- case 10: /* Unlink */
- dsp1 = pop_ptr();
- if (!savestr(0, dsp1) || unlink(buf[0]) == -1) {
- push_err();
- LOG(("@m4 Unlink: failed, dsp1 = %lu, errno = %d",
- dsp1, errno));
- }
- else {
- push_int(0);
- LOG(("@m9 Unlink: succeeded, dsp1 = %lu", dsp1));
- }
- break;
- case 12: /* Chdir */
- dsp1 = pop_ptr();
- if (!savestr(0, dsp1) || chdir(buf[0]) == -1) {
- push_err();
- LOG(("@m4 Chdir: failed, dsp1 = %lu, errno = %d",
- dsp1, errno));
- }
- else {
- push_int(0);
- LOG(("@m9 Chdir: succeeded, dsp1 = %lu", dsp1));
- }
- break;
- case 14: /* Mknod */
- dsp1 = pop_ptr();
- mode = pop_int();
- address = pop_int2();
- if (!savestr(0, dsp1) || mknod(buf[0], mode, address) == -1) {
- push_err();
- LOG(("@m4 Mknod: failed, dsp1 = %lu, mode = %d, address = %d, errno = %d",
- dsp1, mode, address, errno));
- }
- else {
- push_int(0);
- LOG(("@m9 Mknod: succeeded, dsp1 = %lu", dsp1));
- }
- break;
- case 15: /* Chmod */
- dsp1 = pop_ptr();
- mode = pop_int2();
- if (!savestr(0, dsp1) || chmod(buf[0], mode) == -1) {
- push_err();
- LOG(("@m4 Chmod: failed, dsp1 = %lu, mode = %d, errno = %d",
- dsp1, mode, errno));
- }
- else {
- push_int(0);
- LOG(("@m9 Chmod: succeeded, dsp1 = %lu", dsp1));
- }
- break;
- case 16: /* Chown */
- dsp1 = pop_ptr();
- owner = pop_int2();
- group = pop_int2();
- if (!savestr(0, dsp1) || chown(buf[0], owner, group) == -1) {
- push_err();
- LOG(("@m4 Chown: failed, dsp1 = %lu, owner = %d, group = %d, errno = %d",
- dsp1, owner, group, errno));
- }
- else {
- push_int(0);
- LOG(("@m9 Chown: succeeded, dsp1 = %lu", dsp1));
- }
- break;
- case 18: /* Stat */
- dsp1 = pop_ptr(); /* points to file-name space */
- dsp2 = pop_ptr(); /* points to EM-stat-buffer space */
- if ( !savestr(0, dsp1)
- || stat(buf[0], &st_buf) == -1
- || !stat2mem(dsp2, &st_buf)
- ) {
- push_err();
- LOG(("@m4 Stat: failed, dsp1 = %lu, dsp2 = %lu, errno = %d",
- dsp1, dsp2, errno));
- }
- else {
- push_int(0);
- LOG(("@m9 Stat: succeeded, dsp1 = %lu, dsp2 = %lu",
- dsp1, dsp2));
- }
- break;
- case 19: /* Lseek */
- fd = pop_int();
- off = pop_int4();
- whence = pop_int();
- LOG(("@m4 Lseek: fd = %d, off = %ld, whence = %d",
- fd, off, whence));
- if (!good_fd(fd) || (off = lseek(fd, off, whence)) == -1) {
- push_err();
- LOG(("@m9 Lseek: failed, errno = %d", errno));
- }
- else {
- push_i4(off);
- push_int(0);
- LOG(("@m9 Lseek: succeeded, pushed %ld", off));
- }
- break;
- case 20: /* Getpid */
- pid = getpid();
- push_i2(pid);
- LOG(("@m9 Getpid: succeeded, pid = %d", pid));
- break;
- case 21: /* Mount */
- dsp1 = pop_ptr();
- dsp2 = pop_ptr();
- flag = pop_int();
- if ( !savestr(0, dsp1)
- || !savestr(1, dsp2)
- || mount(buf[0], buf[1], flag) == -1
- ) {
- push_err();
- LOG(("@m4 Mount: failed, dsp1 = %lu, dsp2 = %lu, flag = %d, errno = %d",
- dsp1, dsp2, flag, errno));
- }
- else {
- push_int(0);
- LOG(("@m9 Mount: succeeded, dsp1 = %lu, dsp2 = %lu, flag = %d",
- dsp1, dsp2, flag));
- }
- break;
- case 22: /* Umount */
- dsp1 = pop_ptr();
- if ( !savestr(0, dsp1)
- #ifndef BSD4_2 /* from system.h */
- || umount(buf[0]) == -1
- #else /* BSD4_2 */
- || unmount(buf[0]) == -1
- #endif /* BSD4_2 */
- ) {
- push_err();
- LOG(("@m4 Umount: failed, dsp1 = %lu, errno = %d",
- dsp1, errno));
- }
- else {
- push_int(0);
- LOG(("@m9 Mount: succeeded, dsp1 = %lu", dsp1));
- }
- break;
- case 23: /* Setuid */
- userid = pop_int2();
- if (setuid(userid) == -1) {
- push_err();
- LOG(("@m4 Setuid: failed, userid = %d, errno = %d",
- userid, errno));
- }
- else {
- push_int(0);
- LOG(("@m9 Setuid: succeeded, userid = %d", userid));
- }
- break;
- case 24: /* Getuid */
- userid = getuid();
- push_i2(userid);
- LOG(("@m9 Getuid(part 1): real uid = %d", userid));
- userid = geteuid();
- push_i2(userid);
- LOG(("@m9 Getuid(part 2): eff uid = %d", userid));
- break;
- case 25: /* Stime */
- tm = pop_int4();
- #ifndef BSD4_2 /* from system.h */
- rc = stime(&tm);
- #else /* BSD4_2 */
- tv.tv_sec = tm;
- tv.tv_usec = 0; /* zero microseconds */
- rc = settimeofday(&tv, (struct timezone *)0);
- #endif /* BSD4_2 */
- if (rc == -1) {
- push_err();
- LOG(("@m4 Stime: failed, tm = %ld, errno = %d",
- tm, errno));
- }
- else {
- push_int(0);
- LOG(("@m9 Stime: succeeded, tm = %ld", tm));
- }
- break;
- case 26: /* Ptrace */
- request = pop_int();
- pid = pop_int2();
- dsp3 = pop_ptr();
- n = pop_int(); /* Data */
- einval(WPTRACEIMP);
- push_err();
- LOG(("@m4 Ptrace: failed, request = %d, pid = %d, addr = %lu, data = %d, errno = %d",
- request, pid, dsp3, n, errno));
- break;
- case 27: /* Alarm */
- seconds = pop_uns2();
- LOG(("@m9 Alarm(part 1) seconds = %u", seconds));
- seconds = alarm(seconds);
- push_i2(seconds);
- LOG(("@m9 Alarm(part 2) seconds = %u", seconds));
- break;
- case 28: /* Fstat */
- fd = pop_int();
- dsp2 = pop_ptr();
- if ( !good_fd(fd)
- || fstat(fd, &st_buf) == -1
- || !stat2mem(dsp2, &st_buf)
- ) {
- push_err();
- LOG(("@m4 Fstat: failed, fd = %d, dsp2 = %lu, errno = %d",
- fd, dsp2, errno));
- }
- else {
- push_int(0);
- LOG(("@m9 Fstat: succeeded, fd = %d, dsp2 = %lu",
- fd, dsp2));
- }
- break;
- case 29: /* Pause */
- pause();
- LOG(("@m9 Pause: succeeded"));
- break;
- case 30: /* Utime */
- dsp1 = pop_ptr();
- dsp2 = pop_ptr();
- if (memfault(dsp2, 2*INT4SIZE)) {
- push_err();
- LOG(("@m4 Utime: failed, dsp1 = %lu, dsp2 = %lu, errno = %d",
- dsp1, dsp2, errno));
- break;
- }
- actime = mem_ldu(dsp2, INT4SIZE);
- modtime = mem_ldu(dsp2 + INT4SIZE, INT4SIZE);
- #ifdef SYS_V /* from system.h */
- utimbuf.x = actime;
- utimbuf.y = modtime;
- if (!savestr(0, dsp1) || utime(buf[0], &utimbuf) == -1) {
- #else /* SYS_V */
- utimbuf[0] = actime;
- utimbuf[1] = modtime;
- if (!savestr(0, dsp1) || utime(buf[0], utimbuf) == -1) {
- /* may require modification for POSIX ???!!! */
- #endif /* !SYS_V */
- push_err();
- LOG(("@m4 Utime: failed, dsp1 = %lu, dsp2 = %lu, errno = %d",
- dsp1, dsp2, errno));
- }
- else {
- push_int(0);
- LOG(("@m9 Utime: succeeded, dsp1 = %lu, dsp2 = %lu",
- dsp1, dsp2));
- }
- break;
- case 33: /* Access */
- dsp1 = pop_ptr();
- mode = pop_int();
- if (!savestr(0, dsp1) || access(buf[0], mode) == -1) {
- push_err();
- LOG(("@m4 Access: failed, dsp1 = %lu, mode = %d, errno = %d",
- dsp1, mode, errno));
- }
- else {
- push_int(0);
- LOG(("@m9 Access: succeeded, dsp1 = %lu, mode = %d",
- dsp1, mode));
- }
- break;
- case 34: /* Nice */
- incr = pop_int();
- nice(incr);
- LOG(("@m9 Nice: succeeded, incr = %d", incr));
- break;
- case 35: /* Ftime */
- dsp2 = pop_ptr();
- #ifdef BSD_X /* from system.h */
- ftime(&tb_buf);
- #endif /* BSD_X */
- #ifdef SYS_V /* from system.h */
- tb_buf.time = time((time_t*)0);
- tb_buf.millitm = 0;
- tb_buf.timezone = timezone / 60;
- tb_buf.dstflag = daylight;
- #endif /* SYS_V */
- if (!timeb2mem(dsp2, &tb_buf)) {
- push_err();
- LOG(("@m4 Ftime: failed, dsp2 = %lu, errno = %d",
- dsp2, errno));
- }
- else {
- push_int(0);
- LOG(("@m9 Ftime: succeeded, dsp2 = %lu", dsp2));
- }
- break;
- case 36: /* Sync */
- sync();
- LOG(("@m9 Sync: succeeded"));
- break;
- case 37: /* Kill */
- pid = pop_int2();
- sig = pop_int();
- if (kill(pid, sig) == -1) {
- push_err();
- LOG(("@m4 Kill: failed, pid = %d, sig = %d, errno = %d",
- pid, sig, errno));
- }
- else {
- push_int(0);
- LOG(("@m9 Kill: succeeded, pid = %d, sig = %d",
- pid, sig));
- }
- break;
- case 41: /* Dup & Dup2 */
- fd = pop_int();
- fdnew = pop_int();
- if (fd & DUPMASK) {
- int fd1 = fd & ~DUPMASK;/* stripped */
- LOG(("@m4 Dup2: fd1 = %d, fdnew = %d", fd1, fdnew));
- if (!good_fd(fd1)) {
- fdnew = -1;
- goto dup2_error;
- }
- #ifdef BSD_X /* from system.h */
- fdnew = dup2(fd1, fdnew);
- #endif /* BSD_X */
- #ifdef SYS_V /* from system.h */
- {
- /* simulating the semantics of dup2 on SYS_V */
- int dupped = dup(fd1);
- if (dupped < 0 && errno != EMFILE) {
- /* the dup failed, but not
- because of too many open
- file descriptors
- */
- fdnew = dupped;
- }
- else {
- close(dupped);
- close(fdnew);
- fdnew = fcntl(fd1, F_DUPFD, fdnew);
- }
- }
- #endif /* SYS_V */
- dup2_error:;
- }
- else {
- LOG(("@m4 Dup: fd = %d, fdnew = %d", fd, fdnew));
- fdnew = (!good_fd(fd) ? -1 : dup(fd));
- }
- if (fdnew == -1) {
- push_err();
- LOG(("@m4 Dup/Dup2: failed, fdnew = %d, errno = %d",
- fdnew, errno));
- }
- else {
- push_int(fdnew);
- push_int(0);
- LOG(("@m9 Dup/Dup2: succeeded, fdnew = %d", fdnew));
- }
- break;
- case 42: /* Pipe */
- if (pipe(pfds) == -1) {
- push_err();
- LOG(("@m4 Pipe: failed, errno = %d", errno));
- }
- else {
- push_int(pfds[0]);
- push_int(pfds[1]);
- push_int(0);
- LOG(("@m9 Pipe: succeeded, pfds[0] = %d, pfds[1] = %d",
- pfds[0], pfds[1]));
- }
- break;
- case 43: /* Times */
- dsp2 = pop_ptr();
- times(&tm_buf);
- if (!tms2mem(dsp2, &tm_buf)) {
- push_err();
- LOG(("@m4 Times: failed, dsp2 = %lu, errno = %d",
- dsp2, errno));
- }
- else {
- LOG(("@m9 Times: succeeded, dsp2 = %lu", dsp2));
- }
- break;
- case 44: /* Profil */
- dsp1 = pop_ptr(); /* Buffer */
- nbytes = pop_intp(); /* Buffer size */
- off = pop_intp(); /* Offset */
- n = pop_intp(); /* Scale */
- einval(WPROFILIMP);
- push_err();
- LOG(("@m4 Profil: failed, dsp1 = %lu, nbytes = %d, offset = %d, scale = %d, errno = %d",
- dsp1, nbytes, off, n, errno));
- break;
- case 46: /* Setgid */
- groupid = pop_int2();
- if (setgid(groupid) == -1) {
- push_err();
- LOG(("@m4 Setgid: failed, groupid = %d, errno = %d",
- groupid, errno));
- }
- else {
- push_int(0);
- LOG(("@m9 Setgid: succeeded, groupid = %d", groupid));
- }
- break;
- case 47: /* Getgid */
- groupid = getgid();
- push_i2(groupid);
- LOG(("@m9 Getgid(part 1): succeeded, real groupid = %d",
- groupid));
- groupid = getegid();
- push_i2(groupid);
- LOG(("@m9 Getgid(part 2): succeeded, eff groupid = %d",
- groupid));
- break;
- case 48: /* Sigtrp */
- trap_no = pop_int();
- sig_no = pop_int();
-
- if ((old_trap_no = do_sigtrp(trap_no, sig_no)) == -1) {
- push_err();
- LOG(("@m4 Sigtrp: failed, trap_no = %d, sig_no = %d, errno = %d",
- trap_no, sig_no, errno));
- }
- else {
- push_int(old_trap_no);
- push_int(0);
- LOG(("@m9 Sigtrp: succeeded, trap_no = %d, sig_no = %d, old_trap_no = %d",
- trap_no, sig_no, old_trap_no));
- }
- break;
- case 51: /* Acct */
- dsp1 = pop_ptr();
- if (!savestr(0, dsp1) || acct(buf[0]) == -1) {
- push_err();
- LOG(("@m4 Acct: failed, dsp1 = %lu, errno = %d",
- dsp1, errno));
- }
- else {
- push_int(0);
- LOG(("@m9 Acct: succeeded, dsp1 = %lu", dsp1));
- }
- break;
- case 54: /* Ioctl */
- fd = pop_int();
- request = pop_int();
- dsp2 = pop_ptr();
- if (!good_fd(fd) || do_ioctl(fd, request, dsp2) != 0) {
- push_err();
- LOG(("@m4 Ioctl: failed, fd = %d, request = %d, dsp2 = %lu, errno = %d",
- fd, request, dsp2, errno));
- }
- else {
- push_int(0);
- LOG(("@m9 Ioctl: succeeded, fd = %d, request = %d, dsp2 = %lu",
- fd, request, dsp2));
- }
- break;
- case 56: /* Mpxcall */
- request = pop_int(); /* Command */
- dsp1 = pop_ptr(); /* Vec */
- einval(WMPXIMP);
- push_err();
- LOG(("@m4 Mpxcall: failed, request = %d, dsp1 = %lu, errno = %d",
- request, dsp1, errno));
- break;
- case 59: /* Exec */
- dsp1 = pop_ptr();
- dsp2 = pop_ptr();
- dsp3 = pop_ptr();
- if ( !savestr(0, dsp1)
- || !vec(1, 2, dsp2, &argvec)
- || !vec(3, 4, dsp3, &envvec)
- || /* execute results, ignore return code */
- (execve(buf[0], argvec, envvec), 1)
- ) {
- push_err();
- LOG(("@m4 Exece: failed, dsp1 = %lu, dsp2 = %lu, dsp2 = %lu, errno = %d",
- dsp1, dsp2, dsp3, errno));
- }
- break;
- case 60: /* Umask */
- mode = pop_int2();
- oldmask = umask(mode);
- push_int(oldmask);
- LOG(("@m9 Umask: succeeded, mode = %d, oldmask = %d",
- mode, oldmask));
- break;
- case 61: /* Chroot */
- dsp1 = pop_ptr();
- if (!savestr(0, dsp1) || chroot(buf[0]) == -1) {
- push_err();
- LOG(("@m4 Chroot: failed, dsp1 = %lu, errno = %d",
- dsp1, errno));
- }
- else {
- push_int(0);
- LOG(("@m9 Chroot: succeeded, dsp1 = %lu", dsp1));
- }
- break;
- default:
- trap(EBADMON);
- break;
- }
- }
- /* Buffer administration */
- PRIVATE check_buf(n, sz)
- int n;
- size sz;
- {
- if (buf_cnt[n] == 0) {
- buf_cnt[n] = max(128, sz);
- buf[n] = Malloc(buf_cnt[n], "moncall buffer");
- }
- else if (buf_cnt[n] < sz) {
- buf_cnt[n] = allocfrac(sz);
- buf[n] = Realloc(buf[n], buf_cnt[n], "moncall buffer");
- }
- }
- PRIVATE int savestr(n, addr)
- int n;
- ptr addr;
- {
- register size len;
- register char *cp, ch;
- /* determine the length, carefully */
- len = 0;
- do {
- if (memfault(addr + len, 1L)) {
- return 0;
- }
- ch = mem_loc(addr + len);
- len++;
- } while (ch);
- /* allocate enough buffer space */
- check_buf(n, len);
- /* copy the string */
- cp = buf[n];
- do {
- *cp++ = ch = mem_loc(addr);
- addr++;
- } while (ch);
- return 1;
- }
- PRIVATE int vec(n1, n2, addr, vecvec)
- int n1, n2;
- ptr addr;
- char ***vecvec;
- {
- register char *cp1, *cp2;
- ptr p, ldp;
- register int n_ent = 0; /* number of entries */
- register size str = 0; /* total string length */
- /* determine number of elements n_ent */
- p = addr;
- do {
- if (memfault(addr, psize)) {
- return 0;
- }
- ldp = mem_lddp(p);
- if (!savestr(n2, ldp)) {
- return 0;
- }
- str += strlen(buf[n2]) + 1;
- n_ent++;
- p += psize;
- } while (ldp);
- n_ent++;
- *vecvec = (char **) Malloc((size)(n_ent * sizeof (char *)),
- "argvec or envvec in exec()");
- check_buf(n1, str);
- /* copy the elements */
- for ( cp1 = buf[n1], n_ent = 0, p = addr;
- ldp = mem_lddp(p);
- p += psize, n_ent++
- ) {
- if (!savestr(n2, ldp)) {
- return 0;
- }
- (*vecvec)[n_ent] = cp1;
- cp2 = buf[n2];
- while (*cp1++ = *cp2++) {
- /* nothing */
- }
- }
- (*vecvec)[n_ent] = 0;
- return 1;
- }
- int memfault(addr, length)
- ptr addr;
- size length;
- {
- /* centralizes (almost) all memory access tests in MON */
- if (!is_in_mem(addr, length)) {
- efault(WMONFLT);
- return 1;
- }
- return 0;
- }
- efault(wrn)
- int wrn; /* warning number */
- {
- warning(wrn);
- errno = 14; /* EFAULT */
- }
- einval(wrn)
- int wrn; /* warning number */
- {
- warning(wrn);
- errno = 22; /* EINVAL */
- }
|