moncalls.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128
  1. /*
  2. The MON instruction
  3. */
  4. /* $Id$ */
  5. #include "sysidf.h"
  6. #include "log.h"
  7. #include "alloc.h"
  8. #include "shadow.h"
  9. #include <sys/types.h>
  10. #include <sys/stat.h>
  11. #if __STDC__
  12. #include <time.h>
  13. #endif
  14. #include <sys/times.h>
  15. extern int errno; /* UNIX error number */
  16. extern int running; /* from main.c */
  17. extern int fd_limit; /* from io.c */
  18. #define good_fd(fd) (fd < fd_limit ? 1 : (errno = 9 /* EBADF */, 0))
  19. #ifdef BSD_X /* from system.h */
  20. #include <sys/timeb.h>
  21. #endif /* BSD_X */
  22. #ifdef SYS_V
  23. struct timeb { /* non-existing; we use an ad-hoc definition */
  24. long time;
  25. unsigned short millitm;
  26. short timezone, dstflag;
  27. };
  28. #endif /* SYS_V */
  29. #ifdef BSD4_2 /* from system.h */
  30. #include <sys/time.h>
  31. #endif /* BSD4_2 */
  32. #ifdef SYS_V
  33. #include <sys/errno.h>
  34. #undef ERANGE /* collision with trap.h */
  35. #include <fcntl.h>
  36. #include <time.h>
  37. #endif /* SYS_V */
  38. #include <em_abs.h>
  39. #include "logging.h"
  40. #include "global.h"
  41. #include "trap.h"
  42. #include "warn.h"
  43. #include "mem.h"
  44. #define INPUT 0
  45. #define OUTPUT 1
  46. #define DUPMASK 0x40
  47. extern long lseek();
  48. #ifdef SYS_V
  49. extern unsigned int alarm();
  50. extern long time();
  51. extern void sync();
  52. #endif /* SYS_V */
  53. #define INT2SIZE max(wsize, 2L)
  54. #define INT4SIZE max(wsize, 4L)
  55. #define pop_int() ((int) swpop())
  56. #define pop_int2() ((int) spop(INT2SIZE))
  57. #define pop_int4() (spop(INT4SIZE))
  58. #define pop_intp() ((int) spop(psize))
  59. #define pop_uns2() ((unsigned int) upop(INT2SIZE))
  60. #define pop_unsp() ((unsigned int) upop(psize))
  61. #define pop_ptr() (dppop())
  62. #define push_int(a) (wpush((long)(a)))
  63. #define push_i2(a) (npush((long)(a), INT2SIZE))
  64. #define push_i4(a) (npush((long)(a), INT4SIZE))
  65. #define push_unsp(a) (npush((long)(a), psize))
  66. #define push_err() { push_int(errno); push_int(errno); }
  67. /************************************************************************
  68. * Monitor calls. *
  69. * *
  70. * The instruction "MON" expects a wsized integer on top of *
  71. * top of the stack, which identifies the call. Often there *
  72. * are also parameters following this number. The parameters *
  73. * were stacked in reverse order (C convention). *
  74. * The possible parameter types are : *
  75. * *
  76. * 1) int : integer of wordsize *
  77. * 2) int2: integer with size max(2, wordsize) *
  78. * 3) int4: integer with size max(4, wordsize) *
  79. * 4) intp: integer with size of a pointer *
  80. * 5) uns2: unsigned integer with size max(2, wordsize) *
  81. * 6) unsp: unsigned integer with size of a pointer *
  82. * 7) ptr : pointer into data space *
  83. * *
  84. * After the call has been executed, a return code is present *
  85. * on top of the stack. If this return code equals zero, the call *
  86. * succeeded and the results of the call can be found right *
  87. * after the return code. A non zero return code indicates a *
  88. * failure. In this case no results are available and the return *
  89. * code has been pushed twice. *
  90. * *
  91. * Monitor calls such as "ioctl", "stat", "ftime", etc. work *
  92. * with a private buffer to be filled by the call. The fields *
  93. * of the buffer are written to EM-memory separately, possibly *
  94. * with some of the fields aligned. To this end a number of *
  95. * transport routines are assembled in monstruct.[ch]. *
  96. * *
  97. * The EM report specifies a list of UNIX Version 7 -like system *
  98. * calls, not full access to the system calls on the underlying *
  99. * machine. Therefore an attempt has been made to use or emulate *
  100. * the Version 7 system calls on the various machines. A number *
  101. * of 4.1 BSD specific parameters have also been implemented. *
  102. * *
  103. ************************************************************************/
  104. PRIVATE size buf_cnt[5]; /* Current sizes of the buffers */
  105. PRIVATE char *buf[5]; /* Pointers to the buffers */
  106. PRIVATE check_buf();
  107. PRIVATE int savestr();
  108. PRIVATE int vec();
  109. moncall()
  110. {
  111. int n; /* number actually read/written */
  112. int status; /* status for wait-call */
  113. int flag; /* various flag parameters */
  114. int mode; /* various mode parameters */
  115. int oldmask; /* for umask call */
  116. int whence; /* parameter for lseek */
  117. int address; /* address parameter typed int2 */
  118. int owner; /* owner parameter typed int2 */
  119. int group; /* group parameter typed int2 */
  120. int pid; /* pid parameter typed int2 */
  121. int ppid; /* parent process pid */
  122. long off; /* offset parameter */
  123. int pfds[2]; /* pipe file descriptors */
  124. long tm; /* for stime call */
  125. long actime, modtime; /* for utime */
  126. int incr; /* for nice call */
  127. int fd, fdnew; /* file descriptors */
  128. int groupid; /* group id */
  129. int userid; /* user id */
  130. int sig; /* killing signal */
  131. ptr dsp1, dsp2, dsp3; /* Data Space Pointers */
  132. int nbytes; /* number to be read/written */
  133. unsigned int seconds; /* for alarm call */
  134. int trap_no; /* for sigtrp; trap number */
  135. int old_trap_no; /* for sigtrp; old trap number */
  136. int sig_no; /* for sigtrp; signal number */
  137. int request; /* ioctl and ptrace request */
  138. char **envvec; /* environment vector (exec) */
  139. char **argvec; /* argument vector (exec) */
  140. struct stat st_buf; /* private stat buffer */
  141. struct tms tm_buf; /* private tms buffer */
  142. struct timeb tb_buf; /* private timeb buffer */
  143. #ifdef BSD4_2 /* from system.h */
  144. struct timeval tv; /* private timeval buffer */
  145. #endif /* BSD4_2 */
  146. #ifdef SYS_V /* from system.h */
  147. struct {time_t x, y;} utimbuf; /* private utime buffer */
  148. #else /* SYS_V */
  149. time_t utimbuf[2]; /* private utime buffer */
  150. #endif /* !SYS_V */
  151. char *cp;
  152. int nr;
  153. ptr addr;
  154. int rc;
  155. switch (pop_int()) {
  156. case 1: /* Exit */
  157. #ifdef LOGGING
  158. ES_def =
  159. ((st_sh(SP) == UNDEFINED)
  160. || (st_sh(SP + wsize-1) == UNDEFINED)) ?
  161. UNDEFINED : DEFINED;
  162. #else
  163. ES_def = DEFINED;
  164. #endif /* LOGGING */
  165. ES = pop_int();
  166. running = 0; /* stop the machine */
  167. LOG(("@m9 Exit: ES = %ld", ES));
  168. break;
  169. case 2: /* Fork */
  170. ppid = getpid();
  171. if ((pid = fork()) == 0) {
  172. /* Child */
  173. init_ofiles(0); /* Reinitialize */
  174. push_int(ppid); /* Pid of parent */
  175. push_int(1); /* Flag = 1 for child */
  176. push_int(0);
  177. LOG(("@m9 Fork: in child, ppid = %d", ppid));
  178. }
  179. else if (pid > 0) { /* Parent */
  180. incr_mess_id(); /* Incr. id for next child */
  181. push_int(pid); /* Pid of child */
  182. push_int(0); /* Flag = 0 for parent */
  183. push_int(0);
  184. LOG(("@m9 Fork: in parent, cpid = %d", pid));
  185. }
  186. else {
  187. /* fork call failed */
  188. push_err();
  189. LOG(("@m4 Fork: failed, pid = %d, errno = %d",
  190. pid, errno));
  191. }
  192. break;
  193. case 3: /* Read */
  194. fd = pop_int();
  195. dsp1 = pop_ptr();
  196. nbytes = pop_intp();
  197. if (!good_fd(fd))
  198. goto read_error;
  199. if (nbytes < 0) {
  200. errno = 22; /* EINVAL */
  201. goto read_error;
  202. }
  203. check_buf(0, (size)nbytes);
  204. if ((n = read(fd, buf[0], nbytes)) == -1)
  205. goto read_error;
  206. #ifdef LOGGING
  207. if (check_log("@m6")) {
  208. register int i;
  209. for (i = 0; i < n; i++) {
  210. LOG(("@m6 Read: char = '%c'", *(buf[0] + i)));
  211. }
  212. }
  213. #endif /* LOGGING */
  214. if (in_gda(dsp1) && !in_gda(dsp1 + (n-1))) {
  215. efault(WRGDAH);
  216. goto read_error;
  217. }
  218. if (!is_in_mem(dsp1, n)) {
  219. efault(WRUMEM);
  220. goto read_error;
  221. }
  222. for ( nr = n, cp = buf[0], addr = dsp1;
  223. nr;
  224. nr--, addr++, cp++
  225. ) {
  226. if (in_stack(addr)) {
  227. ch_st_prot(addr);
  228. stack_loc(addr) = *cp;
  229. st_int(addr);
  230. }
  231. else {
  232. ch_dt_prot(addr);
  233. data_loc(addr) = *cp;
  234. dt_int(addr);
  235. }
  236. }
  237. push_unsp(n);
  238. push_int(0);
  239. LOG(("@m9 Read: succeeded, n = %d", n));
  240. break;
  241. read_error:
  242. push_err();
  243. LOG(("@m4 Read: failed, n = %d, errno = %d", n, errno));
  244. break;
  245. case 4: /* Write */
  246. fd = pop_int();
  247. dsp1 = pop_ptr();
  248. nbytes = pop_intp();
  249. if (!good_fd(fd))
  250. goto write_error;
  251. if (nbytes < 0) {
  252. errno = 22; /* EINVAL */
  253. goto read_error;
  254. }
  255. if (in_gda(dsp1) && !in_gda(dsp1 + (nbytes-1))) {
  256. efault(WWGDAH);
  257. goto write_error;
  258. }
  259. if (!is_in_mem(dsp1, nbytes)) {
  260. efault(WWUMEM);
  261. goto write_error;
  262. }
  263. #ifdef LOGGING
  264. for (addr = dsp1; addr < dsp1 + nbytes; addr++) {
  265. if (mem_sh(addr) == UNDEFINED) {
  266. warning(in_stack(addr) ? WWLUNDEF : WWGUNDEF);
  267. }
  268. }
  269. #endif /* LOGGING */
  270. check_buf(0, (size)nbytes);
  271. for ( nr = nbytes, addr = dsp1, cp = buf[0];
  272. nr;
  273. nr--, addr++, cp++
  274. ) {
  275. *cp = mem_loc(addr);
  276. }
  277. #ifdef LOGGING
  278. if (check_log("@m6")) {
  279. register int i;
  280. for (i = 0; i < nbytes; i++) {
  281. LOG(("@m6 write: char = '%c'", *(buf[0] + i)));
  282. }
  283. }
  284. #endif /* LOGGING */
  285. if ((n = write(fd, buf[0], nbytes)) == -1)
  286. goto write_error;
  287. push_unsp(n);
  288. push_int(0);
  289. LOG(("@m9 Write: succeeded, n = %d", n));
  290. break;
  291. write_error:
  292. push_err();
  293. LOG(("@m4 Write: failed, n = %d, nbytes = %d, errno = %d",
  294. n, nbytes, errno));
  295. break;
  296. case 5: /* Open */
  297. dsp1 = pop_ptr();
  298. flag = pop_int();
  299. if (!savestr(0, dsp1) || (fd = open(buf[0], flag)) == -1) {
  300. push_err();
  301. LOG(("@m4 Open: failed, file = %lu, flag = %d, fd = %d, errno = %d",
  302. dsp1, flag, fd, errno));
  303. }
  304. else {
  305. push_int(fd);
  306. push_int(0);
  307. LOG(("@m9 Open: succeeded, file = %lu, flag = %d, fd = %d",
  308. dsp1, flag, fd));
  309. }
  310. break;
  311. case 6: /* Close */
  312. fd = pop_int();
  313. if (!good_fd(fd) || close(fd) == -1) {
  314. push_err();
  315. LOG(("@m4 Close: failed, fd = %d, errno = %d",
  316. fd, errno));
  317. }
  318. else {
  319. push_int(0);
  320. LOG(("@m9 Close: succeeded"));
  321. }
  322. break;
  323. case 7: /* Wait */
  324. if ((pid = wait(&status)) == -1) {
  325. push_err();
  326. LOG(("@m4 Wait: failed, status = %d, errno = %d",
  327. status, errno));
  328. }
  329. else {
  330. push_i2(pid);
  331. push_i2(status);
  332. push_int(0);
  333. LOG(("@m9 Wait: succeeded, status = %d, pid = %d",
  334. status, pid));
  335. }
  336. break;
  337. case 8: /* Creat */
  338. dsp1 = pop_ptr();
  339. flag = pop_int();
  340. if (!savestr(0, dsp1) || (fd = creat(buf[0], flag)) == -1) {
  341. push_err();
  342. LOG(("@m4 Creat: failed, dsp1 = %lu, flag = %d, errno = %d",
  343. dsp1, flag, errno));
  344. }
  345. else {
  346. push_int(fd);
  347. push_int(0);
  348. LOG(("@m9 Creat: succeeded, fd = %d", fd));
  349. }
  350. break;
  351. case 9: /* Link */
  352. dsp1 = pop_ptr();
  353. dsp2 = pop_ptr();
  354. if ( !savestr(0, dsp1)
  355. || !savestr(1, dsp2)
  356. || link(buf[0], buf[1]) == -1
  357. ) {
  358. push_err();
  359. LOG(("@m4 Link: failed, dsp1 = %lu, dsp2 = %lu, errno = %d",
  360. dsp1, dsp2, errno));
  361. }
  362. else {
  363. push_int(0);
  364. LOG(("@m9 Link: succeeded, dsp1 = %lu, dsp2 = %lu",
  365. dsp1, dsp2));
  366. }
  367. break;
  368. case 10: /* Unlink */
  369. dsp1 = pop_ptr();
  370. if (!savestr(0, dsp1) || unlink(buf[0]) == -1) {
  371. push_err();
  372. LOG(("@m4 Unlink: failed, dsp1 = %lu, errno = %d",
  373. dsp1, errno));
  374. }
  375. else {
  376. push_int(0);
  377. LOG(("@m9 Unlink: succeeded, dsp1 = %lu", dsp1));
  378. }
  379. break;
  380. case 12: /* Chdir */
  381. dsp1 = pop_ptr();
  382. if (!savestr(0, dsp1) || chdir(buf[0]) == -1) {
  383. push_err();
  384. LOG(("@m4 Chdir: failed, dsp1 = %lu, errno = %d",
  385. dsp1, errno));
  386. }
  387. else {
  388. push_int(0);
  389. LOG(("@m9 Chdir: succeeded, dsp1 = %lu", dsp1));
  390. }
  391. break;
  392. case 14: /* Mknod */
  393. dsp1 = pop_ptr();
  394. mode = pop_int();
  395. address = pop_int2();
  396. if (!savestr(0, dsp1) || mknod(buf[0], mode, address) == -1) {
  397. push_err();
  398. LOG(("@m4 Mknod: failed, dsp1 = %lu, mode = %d, address = %d, errno = %d",
  399. dsp1, mode, address, errno));
  400. }
  401. else {
  402. push_int(0);
  403. LOG(("@m9 Mknod: succeeded, dsp1 = %lu", dsp1));
  404. }
  405. break;
  406. case 15: /* Chmod */
  407. dsp1 = pop_ptr();
  408. mode = pop_int2();
  409. if (!savestr(0, dsp1) || chmod(buf[0], mode) == -1) {
  410. push_err();
  411. LOG(("@m4 Chmod: failed, dsp1 = %lu, mode = %d, errno = %d",
  412. dsp1, mode, errno));
  413. }
  414. else {
  415. push_int(0);
  416. LOG(("@m9 Chmod: succeeded, dsp1 = %lu", dsp1));
  417. }
  418. break;
  419. case 16: /* Chown */
  420. dsp1 = pop_ptr();
  421. owner = pop_int2();
  422. group = pop_int2();
  423. if (!savestr(0, dsp1) || chown(buf[0], owner, group) == -1) {
  424. push_err();
  425. LOG(("@m4 Chown: failed, dsp1 = %lu, owner = %d, group = %d, errno = %d",
  426. dsp1, owner, group, errno));
  427. }
  428. else {
  429. push_int(0);
  430. LOG(("@m9 Chown: succeeded, dsp1 = %lu", dsp1));
  431. }
  432. break;
  433. case 18: /* Stat */
  434. dsp1 = pop_ptr(); /* points to file-name space */
  435. dsp2 = pop_ptr(); /* points to EM-stat-buffer space */
  436. if ( !savestr(0, dsp1)
  437. || stat(buf[0], &st_buf) == -1
  438. || !stat2mem(dsp2, &st_buf)
  439. ) {
  440. push_err();
  441. LOG(("@m4 Stat: failed, dsp1 = %lu, dsp2 = %lu, errno = %d",
  442. dsp1, dsp2, errno));
  443. }
  444. else {
  445. push_int(0);
  446. LOG(("@m9 Stat: succeeded, dsp1 = %lu, dsp2 = %lu",
  447. dsp1, dsp2));
  448. }
  449. break;
  450. case 19: /* Lseek */
  451. fd = pop_int();
  452. off = pop_int4();
  453. whence = pop_int();
  454. LOG(("@m4 Lseek: fd = %d, off = %ld, whence = %d",
  455. fd, off, whence));
  456. if (!good_fd(fd) || (off = lseek(fd, off, whence)) == -1) {
  457. push_err();
  458. LOG(("@m9 Lseek: failed, errno = %d", errno));
  459. }
  460. else {
  461. push_i4(off);
  462. push_int(0);
  463. LOG(("@m9 Lseek: succeeded, pushed %ld", off));
  464. }
  465. break;
  466. case 20: /* Getpid */
  467. pid = getpid();
  468. push_i2(pid);
  469. LOG(("@m9 Getpid: succeeded, pid = %d", pid));
  470. break;
  471. case 21: /* Mount */
  472. dsp1 = pop_ptr();
  473. dsp2 = pop_ptr();
  474. flag = pop_int();
  475. if ( !savestr(0, dsp1)
  476. || !savestr(1, dsp2)
  477. || mount(buf[0], buf[1], flag) == -1
  478. ) {
  479. push_err();
  480. LOG(("@m4 Mount: failed, dsp1 = %lu, dsp2 = %lu, flag = %d, errno = %d",
  481. dsp1, dsp2, flag, errno));
  482. }
  483. else {
  484. push_int(0);
  485. LOG(("@m9 Mount: succeeded, dsp1 = %lu, dsp2 = %lu, flag = %d",
  486. dsp1, dsp2, flag));
  487. }
  488. break;
  489. case 22: /* Umount */
  490. dsp1 = pop_ptr();
  491. if ( !savestr(0, dsp1)
  492. #ifndef BSD4_2 /* from system.h */
  493. || umount(buf[0]) == -1
  494. #else /* BSD4_2 */
  495. || unmount(buf[0]) == -1
  496. #endif /* BSD4_2 */
  497. ) {
  498. push_err();
  499. LOG(("@m4 Umount: failed, dsp1 = %lu, errno = %d",
  500. dsp1, errno));
  501. }
  502. else {
  503. push_int(0);
  504. LOG(("@m9 Mount: succeeded, dsp1 = %lu", dsp1));
  505. }
  506. break;
  507. case 23: /* Setuid */
  508. userid = pop_int2();
  509. if (setuid(userid) == -1) {
  510. push_err();
  511. LOG(("@m4 Setuid: failed, userid = %d, errno = %d",
  512. userid, errno));
  513. }
  514. else {
  515. push_int(0);
  516. LOG(("@m9 Setuid: succeeded, userid = %d", userid));
  517. }
  518. break;
  519. case 24: /* Getuid */
  520. userid = getuid();
  521. push_i2(userid);
  522. LOG(("@m9 Getuid(part 1): real uid = %d", userid));
  523. userid = geteuid();
  524. push_i2(userid);
  525. LOG(("@m9 Getuid(part 2): eff uid = %d", userid));
  526. break;
  527. case 25: /* Stime */
  528. tm = pop_int4();
  529. #ifndef BSD4_2 /* from system.h */
  530. rc = stime(&tm);
  531. #else /* BSD4_2 */
  532. tv.tv_sec = tm;
  533. tv.tv_usec = 0; /* zero microseconds */
  534. rc = settimeofday(&tv, (struct timezone *)0);
  535. #endif /* BSD4_2 */
  536. if (rc == -1) {
  537. push_err();
  538. LOG(("@m4 Stime: failed, tm = %ld, errno = %d",
  539. tm, errno));
  540. }
  541. else {
  542. push_int(0);
  543. LOG(("@m9 Stime: succeeded, tm = %ld", tm));
  544. }
  545. break;
  546. case 26: /* Ptrace */
  547. request = pop_int();
  548. pid = pop_int2();
  549. dsp3 = pop_ptr();
  550. n = pop_int(); /* Data */
  551. einval(WPTRACEIMP);
  552. push_err();
  553. LOG(("@m4 Ptrace: failed, request = %d, pid = %d, addr = %lu, data = %d, errno = %d",
  554. request, pid, dsp3, n, errno));
  555. break;
  556. case 27: /* Alarm */
  557. seconds = pop_uns2();
  558. LOG(("@m9 Alarm(part 1) seconds = %u", seconds));
  559. seconds = alarm(seconds);
  560. push_i2(seconds);
  561. LOG(("@m9 Alarm(part 2) seconds = %u", seconds));
  562. break;
  563. case 28: /* Fstat */
  564. fd = pop_int();
  565. dsp2 = pop_ptr();
  566. if ( !good_fd(fd)
  567. || fstat(fd, &st_buf) == -1
  568. || !stat2mem(dsp2, &st_buf)
  569. ) {
  570. push_err();
  571. LOG(("@m4 Fstat: failed, fd = %d, dsp2 = %lu, errno = %d",
  572. fd, dsp2, errno));
  573. }
  574. else {
  575. push_int(0);
  576. LOG(("@m9 Fstat: succeeded, fd = %d, dsp2 = %lu",
  577. fd, dsp2));
  578. }
  579. break;
  580. case 29: /* Pause */
  581. pause();
  582. LOG(("@m9 Pause: succeeded"));
  583. break;
  584. case 30: /* Utime */
  585. dsp1 = pop_ptr();
  586. dsp2 = pop_ptr();
  587. if (memfault(dsp2, 2*INT4SIZE)) {
  588. push_err();
  589. LOG(("@m4 Utime: failed, dsp1 = %lu, dsp2 = %lu, errno = %d",
  590. dsp1, dsp2, errno));
  591. break;
  592. }
  593. actime = mem_ldu(dsp2, INT4SIZE);
  594. modtime = mem_ldu(dsp2 + INT4SIZE, INT4SIZE);
  595. #ifdef SYS_V /* from system.h */
  596. utimbuf.x = actime;
  597. utimbuf.y = modtime;
  598. if (!savestr(0, dsp1) || utime(buf[0], &utimbuf) == -1) {
  599. #else /* SYS_V */
  600. utimbuf[0] = actime;
  601. utimbuf[1] = modtime;
  602. if (!savestr(0, dsp1) || utime(buf[0], utimbuf) == -1) {
  603. /* may require modification for POSIX ???!!! */
  604. #endif /* !SYS_V */
  605. push_err();
  606. LOG(("@m4 Utime: failed, dsp1 = %lu, dsp2 = %lu, errno = %d",
  607. dsp1, dsp2, errno));
  608. }
  609. else {
  610. push_int(0);
  611. LOG(("@m9 Utime: succeeded, dsp1 = %lu, dsp2 = %lu",
  612. dsp1, dsp2));
  613. }
  614. break;
  615. case 33: /* Access */
  616. dsp1 = pop_ptr();
  617. mode = pop_int();
  618. if (!savestr(0, dsp1) || access(buf[0], mode) == -1) {
  619. push_err();
  620. LOG(("@m4 Access: failed, dsp1 = %lu, mode = %d, errno = %d",
  621. dsp1, mode, errno));
  622. }
  623. else {
  624. push_int(0);
  625. LOG(("@m9 Access: succeeded, dsp1 = %lu, mode = %d",
  626. dsp1, mode));
  627. }
  628. break;
  629. case 34: /* Nice */
  630. incr = pop_int();
  631. nice(incr);
  632. LOG(("@m9 Nice: succeeded, incr = %d", incr));
  633. break;
  634. case 35: /* Ftime */
  635. dsp2 = pop_ptr();
  636. #ifdef BSD_X /* from system.h */
  637. ftime(&tb_buf);
  638. #endif /* BSD_X */
  639. #ifdef SYS_V /* from system.h */
  640. tb_buf.time = time((time_t*)0);
  641. tb_buf.millitm = 0;
  642. tb_buf.timezone = timezone / 60;
  643. tb_buf.dstflag = daylight;
  644. #endif /* SYS_V */
  645. if (!timeb2mem(dsp2, &tb_buf)) {
  646. push_err();
  647. LOG(("@m4 Ftime: failed, dsp2 = %lu, errno = %d",
  648. dsp2, errno));
  649. }
  650. else {
  651. push_int(0);
  652. LOG(("@m9 Ftime: succeeded, dsp2 = %lu", dsp2));
  653. }
  654. break;
  655. case 36: /* Sync */
  656. sync();
  657. LOG(("@m9 Sync: succeeded"));
  658. break;
  659. case 37: /* Kill */
  660. pid = pop_int2();
  661. sig = pop_int();
  662. if (kill(pid, sig) == -1) {
  663. push_err();
  664. LOG(("@m4 Kill: failed, pid = %d, sig = %d, errno = %d",
  665. pid, sig, errno));
  666. }
  667. else {
  668. push_int(0);
  669. LOG(("@m9 Kill: succeeded, pid = %d, sig = %d",
  670. pid, sig));
  671. }
  672. break;
  673. case 41: /* Dup & Dup2 */
  674. fd = pop_int();
  675. fdnew = pop_int();
  676. if (fd & DUPMASK) {
  677. int fd1 = fd & ~DUPMASK;/* stripped */
  678. LOG(("@m4 Dup2: fd1 = %d, fdnew = %d", fd1, fdnew));
  679. if (!good_fd(fd1)) {
  680. fdnew = -1;
  681. goto dup2_error;
  682. }
  683. #ifdef BSD_X /* from system.h */
  684. fdnew = dup2(fd1, fdnew);
  685. #endif /* BSD_X */
  686. #ifdef SYS_V /* from system.h */
  687. {
  688. /* simulating the semantics of dup2 on SYS_V */
  689. int dupped = dup(fd1);
  690. if (dupped < 0 && errno != EMFILE) {
  691. /* the dup failed, but not
  692. because of too many open
  693. file descriptors
  694. */
  695. fdnew = dupped;
  696. }
  697. else {
  698. close(dupped);
  699. close(fdnew);
  700. fdnew = fcntl(fd1, F_DUPFD, fdnew);
  701. }
  702. }
  703. #endif /* SYS_V */
  704. dup2_error:;
  705. }
  706. else {
  707. LOG(("@m4 Dup: fd = %d, fdnew = %d", fd, fdnew));
  708. fdnew = (!good_fd(fd) ? -1 : dup(fd));
  709. }
  710. if (fdnew == -1) {
  711. push_err();
  712. LOG(("@m4 Dup/Dup2: failed, fdnew = %d, errno = %d",
  713. fdnew, errno));
  714. }
  715. else {
  716. push_int(fdnew);
  717. push_int(0);
  718. LOG(("@m9 Dup/Dup2: succeeded, fdnew = %d", fdnew));
  719. }
  720. break;
  721. case 42: /* Pipe */
  722. if (pipe(pfds) == -1) {
  723. push_err();
  724. LOG(("@m4 Pipe: failed, errno = %d", errno));
  725. }
  726. else {
  727. push_int(pfds[0]);
  728. push_int(pfds[1]);
  729. push_int(0);
  730. LOG(("@m9 Pipe: succeeded, pfds[0] = %d, pfds[1] = %d",
  731. pfds[0], pfds[1]));
  732. }
  733. break;
  734. case 43: /* Times */
  735. dsp2 = pop_ptr();
  736. times(&tm_buf);
  737. if (!tms2mem(dsp2, &tm_buf)) {
  738. push_err();
  739. LOG(("@m4 Times: failed, dsp2 = %lu, errno = %d",
  740. dsp2, errno));
  741. }
  742. else {
  743. LOG(("@m9 Times: succeeded, dsp2 = %lu", dsp2));
  744. }
  745. break;
  746. case 44: /* Profil */
  747. dsp1 = pop_ptr(); /* Buffer */
  748. nbytes = pop_intp(); /* Buffer size */
  749. off = pop_intp(); /* Offset */
  750. n = pop_intp(); /* Scale */
  751. einval(WPROFILIMP);
  752. push_err();
  753. LOG(("@m4 Profil: failed, dsp1 = %lu, nbytes = %d, offset = %d, scale = %d, errno = %d",
  754. dsp1, nbytes, off, n, errno));
  755. break;
  756. case 46: /* Setgid */
  757. groupid = pop_int2();
  758. if (setgid(groupid) == -1) {
  759. push_err();
  760. LOG(("@m4 Setgid: failed, groupid = %d, errno = %d",
  761. groupid, errno));
  762. }
  763. else {
  764. push_int(0);
  765. LOG(("@m9 Setgid: succeeded, groupid = %d", groupid));
  766. }
  767. break;
  768. case 47: /* Getgid */
  769. groupid = getgid();
  770. push_i2(groupid);
  771. LOG(("@m9 Getgid(part 1): succeeded, real groupid = %d",
  772. groupid));
  773. groupid = getegid();
  774. push_i2(groupid);
  775. LOG(("@m9 Getgid(part 2): succeeded, eff groupid = %d",
  776. groupid));
  777. break;
  778. case 48: /* Sigtrp */
  779. trap_no = pop_int();
  780. sig_no = pop_int();
  781. if ((old_trap_no = do_sigtrp(trap_no, sig_no)) == -1) {
  782. push_err();
  783. LOG(("@m4 Sigtrp: failed, trap_no = %d, sig_no = %d, errno = %d",
  784. trap_no, sig_no, errno));
  785. }
  786. else {
  787. push_int(old_trap_no);
  788. push_int(0);
  789. LOG(("@m9 Sigtrp: succeeded, trap_no = %d, sig_no = %d, old_trap_no = %d",
  790. trap_no, sig_no, old_trap_no));
  791. }
  792. break;
  793. case 51: /* Acct */
  794. dsp1 = pop_ptr();
  795. if (!savestr(0, dsp1) || acct(buf[0]) == -1) {
  796. push_err();
  797. LOG(("@m4 Acct: failed, dsp1 = %lu, errno = %d",
  798. dsp1, errno));
  799. }
  800. else {
  801. push_int(0);
  802. LOG(("@m9 Acct: succeeded, dsp1 = %lu", dsp1));
  803. }
  804. break;
  805. case 54: /* Ioctl */
  806. fd = pop_int();
  807. request = pop_int();
  808. dsp2 = pop_ptr();
  809. if (!good_fd(fd) || do_ioctl(fd, request, dsp2) != 0) {
  810. push_err();
  811. LOG(("@m4 Ioctl: failed, fd = %d, request = %d, dsp2 = %lu, errno = %d",
  812. fd, request, dsp2, errno));
  813. }
  814. else {
  815. push_int(0);
  816. LOG(("@m9 Ioctl: succeeded, fd = %d, request = %d, dsp2 = %lu",
  817. fd, request, dsp2));
  818. }
  819. break;
  820. case 56: /* Mpxcall */
  821. request = pop_int(); /* Command */
  822. dsp1 = pop_ptr(); /* Vec */
  823. einval(WMPXIMP);
  824. push_err();
  825. LOG(("@m4 Mpxcall: failed, request = %d, dsp1 = %lu, errno = %d",
  826. request, dsp1, errno));
  827. break;
  828. case 59: /* Exec */
  829. dsp1 = pop_ptr();
  830. dsp2 = pop_ptr();
  831. dsp3 = pop_ptr();
  832. if ( !savestr(0, dsp1)
  833. || !vec(1, 2, dsp2, &argvec)
  834. || !vec(3, 4, dsp3, &envvec)
  835. || /* execute results, ignore return code */
  836. (execve(buf[0], argvec, envvec), 1)
  837. ) {
  838. push_err();
  839. LOG(("@m4 Exece: failed, dsp1 = %lu, dsp2 = %lu, dsp2 = %lu, errno = %d",
  840. dsp1, dsp2, dsp3, errno));
  841. }
  842. break;
  843. case 60: /* Umask */
  844. mode = pop_int2();
  845. oldmask = umask(mode);
  846. push_int(oldmask);
  847. LOG(("@m9 Umask: succeeded, mode = %d, oldmask = %d",
  848. mode, oldmask));
  849. break;
  850. case 61: /* Chroot */
  851. dsp1 = pop_ptr();
  852. if (!savestr(0, dsp1) || chroot(buf[0]) == -1) {
  853. push_err();
  854. LOG(("@m4 Chroot: failed, dsp1 = %lu, errno = %d",
  855. dsp1, errno));
  856. }
  857. else {
  858. push_int(0);
  859. LOG(("@m9 Chroot: succeeded, dsp1 = %lu", dsp1));
  860. }
  861. break;
  862. default:
  863. trap(EBADMON);
  864. break;
  865. }
  866. }
  867. /* Buffer administration */
  868. PRIVATE check_buf(n, sz)
  869. int n;
  870. size sz;
  871. {
  872. if (buf_cnt[n] == 0) {
  873. buf_cnt[n] = max(128, sz);
  874. buf[n] = Malloc(buf_cnt[n], "moncall buffer");
  875. }
  876. else if (buf_cnt[n] < sz) {
  877. buf_cnt[n] = allocfrac(sz);
  878. buf[n] = Realloc(buf[n], buf_cnt[n], "moncall buffer");
  879. }
  880. }
  881. PRIVATE int savestr(n, addr)
  882. int n;
  883. ptr addr;
  884. {
  885. register size len;
  886. register char *cp, ch;
  887. /* determine the length, carefully */
  888. len = 0;
  889. do {
  890. if (memfault(addr + len, 1L)) {
  891. return 0;
  892. }
  893. ch = mem_loc(addr + len);
  894. len++;
  895. } while (ch);
  896. /* allocate enough buffer space */
  897. check_buf(n, len);
  898. /* copy the string */
  899. cp = buf[n];
  900. do {
  901. *cp++ = ch = mem_loc(addr);
  902. addr++;
  903. } while (ch);
  904. return 1;
  905. }
  906. PRIVATE int vec(n1, n2, addr, vecvec)
  907. int n1, n2;
  908. ptr addr;
  909. char ***vecvec;
  910. {
  911. register char *cp1, *cp2;
  912. ptr p, ldp;
  913. register int n_ent = 0; /* number of entries */
  914. register size str = 0; /* total string length */
  915. /* determine number of elements n_ent */
  916. p = addr;
  917. do {
  918. if (memfault(addr, psize)) {
  919. return 0;
  920. }
  921. ldp = mem_lddp(p);
  922. if (!savestr(n2, ldp)) {
  923. return 0;
  924. }
  925. str += strlen(buf[n2]) + 1;
  926. n_ent++;
  927. p += psize;
  928. } while (ldp);
  929. n_ent++;
  930. *vecvec = (char **) Malloc((size)(n_ent * sizeof (char *)),
  931. "argvec or envvec in exec()");
  932. check_buf(n1, str);
  933. /* copy the elements */
  934. for ( cp1 = buf[n1], n_ent = 0, p = addr;
  935. ldp = mem_lddp(p);
  936. p += psize, n_ent++
  937. ) {
  938. if (!savestr(n2, ldp)) {
  939. return 0;
  940. }
  941. (*vecvec)[n_ent] = cp1;
  942. cp2 = buf[n2];
  943. while (*cp1++ = *cp2++) {
  944. /* nothing */
  945. }
  946. }
  947. (*vecvec)[n_ent] = 0;
  948. return 1;
  949. }
  950. int memfault(addr, length)
  951. ptr addr;
  952. size length;
  953. {
  954. /* centralizes (almost) all memory access tests in MON */
  955. if (!is_in_mem(addr, length)) {
  956. efault(WMONFLT);
  957. return 1;
  958. }
  959. return 0;
  960. }
  961. efault(wrn)
  962. int wrn; /* warning number */
  963. {
  964. warning(wrn);
  965. errno = 14; /* EFAULT */
  966. }
  967. einval(wrn)
  968. int wrn; /* warning number */
  969. {
  970. warning(wrn);
  971. errno = 22; /* EINVAL */
  972. }