|
|
1.1 root 1: /*
2:
1.1.1.3 root 3: Copyright 1990,1991,1992 Eric R. Smith.
4:
1.1.1.6 ! root 5: Copyright 1992,1993,1994 Atari Corporation.
1.1.1.3 root 6:
7: All rights reserved.
1.1 root 8:
9: */
10:
11:
12:
13: /* miscellaneous DOS functions, and the DOS initialization function */
14:
15:
16:
17: #include "mint.h"
18:
19:
20:
1.1.1.6 ! root 21: #define DOS_MAX 0x160
1.1 root 22:
23:
24:
25: Func dos_tab[DOS_MAX];
26:
27: short dos_max = DOS_MAX;
28:
29:
30:
31: static void alarmme P_((PROC *));
32:
1.1.1.6 ! root 33: static void itimer_real_me P_((PROC *p));
! 34:
! 35: static void itimer_virtual_me P_((PROC *p));
! 36:
! 37: static void itimer_prof_me P_((PROC *p));
! 38:
1.1 root 39:
40:
1.1.1.2 root 41: long ARGS_ON_STACK
1.1 root 42:
43: s_version()
44:
45: {
46:
47: return Sversion();
48:
49: }
50:
51:
52:
53: /*
54:
55: * Super(new_ssp): change to supervisor mode.
56:
57: */
58:
59:
60:
1.1.1.2 root 61: long ARGS_ON_STACK
1.1 root 62:
63: s_uper(new_ssp)
64:
65: long new_ssp;
66:
67: {
68:
69: int in_super;
70:
71: long r;
72:
73:
74:
1.1.1.2 root 75: TRACE(("Super"));
1.1 root 76:
77: in_super = curproc->ctxt[SYSCALL].sr & 0x2000;
78:
79:
80:
81: if (new_ssp == 1) {
82:
83: r = in_super ? -1L : 0;
84:
85: }
86:
87: else {
88:
89: curproc->ctxt[SYSCALL].sr ^= 0x2000;
90:
91: r = curproc->ctxt[SYSCALL].ssp;
92:
93: if (in_super) {
94:
95: if (new_ssp == 0) {
96:
1.1.1.2 root 97: DEBUG(("bad Super call"));
1.1 root 98:
99: raise(SIGSYS);
100:
101: }
102:
103: else {
104:
105: curproc->ctxt[SYSCALL].usp =
106:
107: curproc->ctxt[SYSCALL].ssp;
108:
109: curproc->ctxt[SYSCALL].ssp = new_ssp;
110:
111: }
112:
113: }
114:
115: else {
116:
117: curproc->ctxt[SYSCALL].ssp =
118:
119: new_ssp ? new_ssp : curproc->ctxt[SYSCALL].usp;
120:
121: }
122:
123: }
124:
125: return r;
126:
127: }
128:
129:
130:
131: /*
132:
133: * get/set time and date functions
134:
135: */
136:
1.1.1.2 root 137: long ARGS_ON_STACK t_getdate() { return datestamp; }
1.1 root 138:
1.1.1.2 root 139: long ARGS_ON_STACK t_gettime() { return timestamp; }
1.1 root 140:
141:
142:
1.1.1.2 root 143: long ARGS_ON_STACK t_setdate(date)
1.1 root 144:
145: int date;
146:
147: {
148:
1.1.1.4 root 149: long r;
150:
151:
152:
153: /* Only the superuser may set date or time */
154:
155: if (curproc->euid != 0)
156:
157: return EACCDN;
158:
159: r = Tsetdate(date);
1.1 root 160:
161: datestamp = Tgetdate();
162:
163: return r;
164:
165: }
166:
167:
168:
1.1.1.2 root 169: long ARGS_ON_STACK t_settime(time)
1.1 root 170:
171: int time;
172:
173: {
174:
1.1.1.4 root 175: long r;
176:
177:
178:
179: if (curproc->euid != 0)
180:
181: return EACCDN;
182:
183: r = Tsettime(time);
1.1 root 184:
185: timestamp = Tgettime();
186:
187: return r;
188:
189: }
190:
191:
192:
193: /*
194:
195: * GEMDOS extension: Syield(): give up the processor if any other
196:
197: * processes are waiting. Always returns 0.
198:
199: */
200:
201:
202:
1.1.1.2 root 203: long ARGS_ON_STACK
1.1 root 204:
205: s_yield()
206:
207: {
208:
209: /* reward the nice process */
210:
211: curproc->curpri = curproc->pri;
212:
213: sleep(READY_Q, curproc->wait_cond);
214:
215: return 0;
216:
217: }
218:
219:
220:
221: /*
222:
223: * GEMDOS extension:
224:
225: * Prenice(pid, delta) sets the process priority level for process pid.
226:
227: * A "nice" value < 0 increases priority, one > 0 decreases it.
228:
229: * Always returns the new priority (so Prenice(pid, 0) queries the current
230:
231: * priority).
232:
233: *
234:
235: * NOTE: for backward compatibility, Pnice(delta) is provided and is equivalent
236:
237: * to Prenice(Pgetpid(), delta)
238:
239: */
240:
241:
242:
1.1.1.2 root 243: long ARGS_ON_STACK
1.1 root 244:
245: p_renice(pid, delta)
246:
247: int pid, delta;
248:
249: {
250:
251: PROC *p;
252:
253:
254:
1.1.1.2 root 255: if (pid <= 0 || 0 == (p = pid2proc(pid))) {
1.1 root 256:
257: return EFILNF;
258:
259: }
260:
261:
262:
263: if (curproc->euid && curproc->euid != p->ruid
264:
265: && curproc->ruid != p->ruid) {
266:
1.1.1.2 root 267: DEBUG(("Prenice: process ownership error"));
1.1 root 268:
269: return EACCDN;
270:
271: }
272:
273: p->pri -= delta;
274:
275: if (p->pri < MIN_NICE) p->pri = MIN_NICE;
276:
277: if (p->pri > MAX_NICE) p->pri = MAX_NICE;
278:
279: p->curpri = p->pri;
280:
281: return ((long)p->pri) & 0x0ffff;
282:
283: }
284:
285:
286:
1.1.1.2 root 287: long ARGS_ON_STACK
1.1 root 288:
289: p_nice(delta)
290:
291: int delta;
292:
293: {
294:
295: return p_renice(curproc->pid,delta);
296:
297: }
298:
299:
300:
301: /*
302:
303: * GEMDOS extensions: routines for getting/setting process i.d.'s and
304:
305: * user i.d.'s
306:
307: */
308:
309:
310:
1.1.1.2 root 311: long ARGS_ON_STACK p_getpid() { return curproc->pid; }
1.1 root 312:
313:
314:
1.1.1.2 root 315: long ARGS_ON_STACK p_getppid() { return curproc->ppid; }
1.1 root 316:
317:
318:
1.1.1.2 root 319: long ARGS_ON_STACK p_getpgrp() { return curproc->pgrp; }
1.1 root 320:
321:
322:
323: /* note: Psetpgrp(0, ...) is equivalent to Psetpgrp(Pgetpid(), ...) */
324:
325: /* also note: Psetpgrp(x, 0) is equivalent to Psetpgrp(x, x) */
326:
327:
328:
1.1.1.2 root 329: long ARGS_ON_STACK p_setpgrp(pid, newgrp)
1.1 root 330:
331: int pid, newgrp;
332:
333: {
334:
335: PROC *p;
336:
337:
338:
339: if (pid == 0)
340:
341: p = curproc;
342:
1.1.1.2 root 343: else if (0 == (p = pid2proc(pid)))
1.1 root 344:
345: return EFILNF;
346:
347: if ( (curproc->euid) && (p->ruid != curproc->ruid)
348:
349: && (p->ppid != curproc->pid) )
350:
351: return EACCDN;
352:
353:
354:
1.1.1.3 root 355: if (newgrp < 0)
356:
357: return p->pgrp;
358:
359:
360:
1.1 root 361: if (newgrp == 0)
362:
363: newgrp = p->pid;
364:
365:
366:
367: return (p->pgrp = newgrp);
368:
369: }
370:
371:
372:
1.1.1.2 root 373: long ARGS_ON_STACK p_getuid() { return curproc->ruid; }
1.1 root 374:
1.1.1.2 root 375: long ARGS_ON_STACK p_getgid() { return curproc->rgid; }
1.1 root 376:
1.1.1.2 root 377: long ARGS_ON_STACK p_geteuid() { return curproc->euid; }
1.1 root 378:
1.1.1.2 root 379: long ARGS_ON_STACK p_getegid() { return curproc->egid; }
1.1 root 380:
381:
382:
1.1.1.2 root 383: long ARGS_ON_STACK
1.1 root 384:
385: p_setuid(id)
386:
387: int id;
388:
389: {
390:
1.1.1.6 ! root 391: if (curproc->euid == 0 || curproc->euid == id || curproc->ruid == id) {
1.1 root 392:
393: curproc->ruid = curproc->euid = id;
394:
395: return id;
396:
397: }
398:
399: return EACCDN;
400:
401: }
402:
403:
404:
1.1.1.2 root 405: long ARGS_ON_STACK
1.1 root 406:
407: p_setgid(id)
408:
409: int id;
410:
411: {
412:
1.1.1.6 ! root 413: if (curproc->euid == 0 || curproc->rgid == id) {
1.1 root 414:
415: curproc->egid = curproc->rgid = id;
416:
417: return id;
418:
419: }
420:
421: return EACCDN;
422:
423: }
424:
425:
426:
1.1.1.6 ! root 427: /* uk: set effective uid/gid but leave the real uid/gid unchanged. */
! 428:
! 429: long ARGS_ON_STACK
! 430:
! 431: p_seteuid(id)
! 432:
! 433: int id;
! 434:
! 435: {
! 436:
! 437: if (curproc->euid == 0 || curproc->ruid == id) {
! 438:
! 439: curproc->euid = id;
! 440:
! 441: return id;
! 442:
! 443: }
! 444:
! 445: return EACCDN;
! 446:
! 447: }
! 448:
! 449:
! 450:
! 451: long ARGS_ON_STACK
! 452:
! 453: p_setegid(id)
! 454:
! 455: int id;
! 456:
! 457: {
! 458:
! 459: if (curproc->euid == 0 || curproc->egid == 0 || curproc->rgid == id) {
! 460:
! 461: curproc->egid = id;
! 462:
! 463: return id;
! 464:
! 465: }
! 466:
! 467: return EACCDN;
! 468:
! 469: }
! 470:
! 471:
! 472:
! 473: /* tesche: audit user id functions, these id's never change once set to != 0
! 474:
! 475: * and can therefore be used to determine who the initially logged in user was.
! 476:
! 477: */
! 478:
! 479: long ARGS_ON_STACK
! 480:
! 481: p_getauid()
! 482:
! 483: {
! 484:
! 485: return curproc->auid;
! 486:
! 487: }
! 488:
! 489:
! 490:
! 491: long ARGS_ON_STACK
! 492:
! 493: p_setauid(id)
! 494:
! 495: int id;
! 496:
! 497: {
! 498:
! 499: if (curproc->auid)
! 500:
! 501: return EACCDN; /* this may only be changed once */
! 502:
! 503:
! 504:
! 505: return (curproc->auid = id);
! 506:
! 507: }
! 508:
! 509:
! 510:
! 511: /* tesche: get/set supplemantary group id's.
! 512:
! 513: */
! 514:
! 515: long ARGS_ON_STACK
! 516:
! 517: p_getgroups(gidsetlen, gidset)
! 518:
! 519: int gidsetlen;
! 520:
! 521: int gidset[];
! 522:
! 523: {
! 524:
! 525: int i;
! 526:
! 527:
! 528:
! 529: if (gidsetlen == 0)
! 530:
! 531: return curproc->ngroups;
! 532:
! 533:
! 534:
! 535: if (gidsetlen < curproc->ngroups)
! 536:
! 537: return ERANGE;
! 538:
! 539:
! 540:
! 541: for (i=0; i<curproc->ngroups; i++)
! 542:
! 543: gidset[i] = curproc->ngroup[i];
! 544:
! 545:
! 546:
! 547: return curproc->ngroups;
! 548:
! 549: }
! 550:
! 551:
! 552:
! 553: long ARGS_ON_STACK
! 554:
! 555: p_setgroups(ngroups, gidset)
! 556:
! 557: int ngroups;
! 558:
! 559: int gidset[];
! 560:
! 561: {
! 562:
! 563: int i;
! 564:
! 565:
! 566:
! 567: if (curproc->euid)
! 568:
! 569: return EACCDN; /* only superuser may change this */
! 570:
! 571:
! 572:
! 573: if ((ngroups < 0) || (ngroups > NGROUPS_MAX))
! 574:
! 575: return ERANGE;
! 576:
! 577:
! 578:
! 579: curproc->ngroups = ngroups;
! 580:
! 581: for (i=0; i<ngroups; i++)
! 582:
! 583: curproc->ngroup[i] = gidset[i];
! 584:
! 585:
! 586:
! 587: return ngroups;
! 588:
! 589: }
! 590:
! 591:
! 592:
1.1 root 593: /*
594:
595: * a way to get/set process-specific user information. the user information
596:
597: * longword is set to "arg", unless arg is -1. In any case, the old
598:
599: * value of the longword is returned.
600:
601: */
602:
603:
604:
1.1.1.2 root 605: long ARGS_ON_STACK
1.1 root 606:
607: p_usrval(arg)
608:
609: long arg;
610:
611: {
612:
613: long r;
614:
615:
616:
1.1.1.2 root 617: TRACE(("Pusrval"));
1.1 root 618:
619: r = curproc->usrdata;
620:
621: if (arg != -1L)
622:
623: curproc->usrdata = arg;
624:
625: return r;
626:
627: }
628:
629:
630:
631: /*
632:
633: * set the file creation mask to "mode". Returns the old value of the
634:
635: * mask.
636:
637: */
638:
1.1.1.2 root 639: long ARGS_ON_STACK p_umask(mode)
1.1 root 640:
641: unsigned mode;
642:
643: {
644:
645: long oldmask = curproc->umask;
646:
647:
648:
649: curproc->umask = mode & (~S_IFMT);
650:
651: return oldmask;
652:
653: }
654:
655:
656:
657: /*
658:
659: * get/set the domain of a process. domain 0 is the default (TOS) domain.
660:
661: * domain 1 is the MiNT domain. for now, domain affects read/write system
662:
663: * calls and filename translation.
664:
665: */
666:
667:
668:
1.1.1.2 root 669: long ARGS_ON_STACK
1.1 root 670:
671: p_domain(arg)
672:
673: int arg;
674:
675: {
676:
677: long r;
678:
1.1.1.2 root 679: TRACE(("Pdomain(%d)", arg));
1.1 root 680:
681:
682:
683: r = curproc->domain;
684:
685: if (arg >= 0)
686:
687: curproc->domain = arg;
688:
689: return r;
690:
691: }
692:
693:
694:
695: /*
696:
697: * get process resource usage. 8 longwords are returned, as follows:
698:
699: * r[0] == system time used by process
700:
701: * r[1] == user time used by process
702:
703: * r[2] == system time used by process' children
704:
705: * r[3] == user time used by process' children
706:
707: * r[4] == memory used by process
708:
709: * r[5] - r[7]: reserved for future use
710:
711: */
712:
713:
714:
1.1.1.2 root 715: long ARGS_ON_STACK
1.1 root 716:
717: p_rusage(r)
718:
719: long *r;
720:
721: {
722:
723: r[0] = curproc->systime;
724:
725: r[1] = curproc->usrtime;
726:
727: r[2] = curproc->chldstime;
728:
729: r[3] = curproc->chldutime;
730:
731: r[4] = memused(curproc);
732:
733: return 0;
734:
735: }
736:
737:
738:
739: /*
740:
741: * get/set resource limits i to value v. The old limit is always returned;
742:
743: * if v == -1, the limit is unchanged, otherwise it is set to v. Possible
744:
745: * values for i are:
746:
747: * 1: max. cpu time (milliseconds)
748:
749: * 2: max. core memory allowed
750:
751: * 3: max. amount of malloc'd memory allowed
752:
753: */
754:
1.1.1.2 root 755: long ARGS_ON_STACK
1.1 root 756:
757: p_setlimit(i, v)
758:
759: int i;
760:
761: long v;
762:
763: {
764:
765: long oldlimit;
766:
767:
768:
769: switch(i) {
770:
771: case 1:
772:
773: oldlimit = curproc->maxcpu;
774:
775: if (v >= 0) curproc->maxcpu = v;
776:
777: break;
778:
779: case 2:
780:
781: oldlimit = curproc->maxcore;
782:
783: if (v >= 0) {
784:
785: curproc->maxcore = v;
786:
787: recalc_maxmem(curproc);
788:
789: }
790:
791: break;
792:
793: case 3:
794:
795: oldlimit = curproc->maxdata;
796:
797: if (v >= 0) {
798:
799: curproc->maxdata = v;
800:
801: recalc_maxmem(curproc);
802:
803: }
804:
805: break;
806:
807: default:
808:
1.1.1.2 root 809: DEBUG(("Psetlimit: invalid mode %d", i));
1.1 root 810:
811: return EINVFN;
812:
813: }
814:
1.1.1.2 root 815: TRACE(("p_setlimit(%d, %ld): oldlimit = %ld", i, v, oldlimit));
1.1 root 816:
817: return oldlimit;
818:
819: }
820:
821:
822:
823: /*
824:
825: * pause: just sleeps on IO_Q, with wait_cond == -1. only a signal will
826:
827: * wake us up
828:
829: */
830:
831:
832:
1.1.1.2 root 833: long ARGS_ON_STACK
1.1 root 834:
835: p_pause()
836:
837: {
838:
1.1.1.2 root 839: TRACE(("Pause"));
840:
1.1 root 841: sleep(IO_Q, -1L);
842:
843: return 0;
844:
845: }
846:
847:
848:
849: /*
850:
851: * helper function for t_alarm: this will be called when the timer goes
852:
853: * off, and raises SIGALRM
854:
855: */
856:
857:
858:
859: static void
860:
861: alarmme(p)
862:
863: PROC *p;
864:
865: {
866:
867: p->alarmtim = 0;
868:
869: post_sig(p, SIGALRM);
870:
871: }
872:
873:
874:
875: /*
876:
877: * t_alarm(x): set the alarm clock to go off in "x" seconds. returns the
878:
879: * old value of the alarm clock
880:
881: */
882:
883:
884:
1.1.1.2 root 885: long ARGS_ON_STACK
1.1 root 886:
887: t_alarm(x)
888:
889: long x;
890:
891: {
892:
893: long oldalarm;
894:
1.1.1.5 root 895: oldalarm = t_malarm(x*1000);
896:
897: oldalarm = (oldalarm+999)/1000; /* convert to seconds */
898:
899: return oldalarm;
900:
901: }
902:
903:
904:
905: /*
906:
907: * t_malarm(x): set the alarm clock to go off in "x" milliseconds. returns
908:
909: * the old value ofthe alarm clock
910:
911: */
912:
913:
914:
915: long ARGS_ON_STACK
916:
917: t_malarm(x)
918:
919: long x;
920:
921: {
922:
923: long oldalarm;
924:
1.1 root 925: TIMEOUT *t;
926:
927:
928:
929: /* see how many milliseconds there were to the alarm timeout */
930:
931: oldalarm = 0;
932:
933:
934:
935: if (curproc->alarmtim) {
936:
937: for (t = tlist; t; t = t->next) {
938:
939: oldalarm += t->when;
940:
941: if (t == curproc->alarmtim)
942:
943: goto foundalarm;
944:
945: }
946:
1.1.1.2 root 947: DEBUG(("Talarm: old alarm not found!"));
1.1 root 948:
949: oldalarm = 0;
950:
951: curproc->alarmtim = 0;
952:
953: foundalarm:
954:
955: ;
956:
957: }
958:
959:
960:
961: /* we were just querying the alarm */
962:
963: if (x < 0)
964:
965: return oldalarm;
966:
967:
968:
969: /* cancel old alarm */
970:
971: if (curproc->alarmtim)
972:
973: canceltimeout(curproc->alarmtim);
974:
975:
976:
1.1.1.5 root 977: /* add a new alarm, to occur in x milliseconds */
1.1 root 978:
979: if (x)
980:
1.1.1.5 root 981: curproc->alarmtim = addtimeout(x, alarmme);
1.1 root 982:
983: else
984:
985: curproc->alarmtim = 0;
986:
987:
988:
989: return oldalarm;
990:
991: }
992:
993:
994:
1.1.1.6 ! root 995: #define ITIMER_REAL 0
! 996:
! 997: #define ITIMER_VIRTUAL 1
! 998:
! 999: #define ITIMER_PROF 2
! 1000:
! 1001:
! 1002:
! 1003: /*
! 1004:
! 1005: * helper function for t_setitimer: this will be called when the ITIMER_REAL
! 1006:
! 1007: * timer goes off
! 1008:
! 1009: */
! 1010:
! 1011:
! 1012:
! 1013: static void
! 1014:
! 1015: itimer_real_me(p)
! 1016:
! 1017: PROC *p;
! 1018:
! 1019: {
! 1020:
! 1021: PROC *real_curproc;
! 1022:
! 1023:
! 1024:
! 1025: real_curproc = curproc;
! 1026:
! 1027: curproc = p;
! 1028:
! 1029: if (p->itimer[ITIMER_REAL].interval)
! 1030:
! 1031: p->itimer[ITIMER_REAL].timeout =
! 1032:
! 1033: addtimeout(p->itimer[ITIMER_REAL].interval, itimer_real_me);
! 1034:
! 1035: else
! 1036:
! 1037: p->itimer[ITIMER_REAL].timeout = 0;
! 1038:
! 1039:
! 1040:
! 1041: curproc = real_curproc;
! 1042:
! 1043: post_sig(p, SIGALRM);
! 1044:
! 1045: }
! 1046:
! 1047:
! 1048:
! 1049: /*
! 1050:
! 1051: * helper function for t_setitimer: this will be called when the ITIMER_VIRTUAL
! 1052:
! 1053: * timer goes off
! 1054:
! 1055: */
! 1056:
! 1057:
! 1058:
! 1059: static void
! 1060:
! 1061: itimer_virtual_me(p)
! 1062:
! 1063: PROC *p;
! 1064:
! 1065: {
! 1066:
! 1067: PROC *real_curproc;
! 1068:
! 1069: long timeleft;
! 1070:
! 1071:
! 1072:
! 1073: real_curproc = curproc;
! 1074:
! 1075: curproc = p;
! 1076:
! 1077: timeleft = p->itimer[ITIMER_VIRTUAL].reqtime
! 1078:
! 1079: - (p->systime - p->itimer[ITIMER_VIRTUAL].startsystime);
! 1080:
! 1081: if (timeleft > 0) {
! 1082:
! 1083: p->itimer[ITIMER_VIRTUAL].timeout =
! 1084:
! 1085: addtimeout(timeleft, itimer_virtual_me);
! 1086:
! 1087: } else {
! 1088:
! 1089: timeleft = p->itimer[ITIMER_VIRTUAL].interval;
! 1090:
! 1091: if (timeleft == 0) {
! 1092:
! 1093: p->itimer[ITIMER_VIRTUAL].timeout = 0;
! 1094:
! 1095: } else {
! 1096:
! 1097: p->itimer[ITIMER_VIRTUAL].reqtime = timeleft;
! 1098:
! 1099: p->itimer[ITIMER_VIRTUAL].startsystime = p->systime;
! 1100:
! 1101: p->itimer[ITIMER_VIRTUAL].startusrtime = p->usrtime;
! 1102:
! 1103: p->itimer[ITIMER_VIRTUAL].timeout =
! 1104:
! 1105: addtimeout(timeleft, itimer_virtual_me);
! 1106:
! 1107: }
! 1108:
! 1109: post_sig(p, SIGVTALRM);
! 1110:
! 1111: }
! 1112:
! 1113: curproc = real_curproc;
! 1114:
! 1115: }
! 1116:
! 1117:
! 1118:
! 1119: /*
! 1120:
! 1121: * helper function for t_setitimer: this will be called when the ITIMER_PROF
! 1122:
! 1123: * timer goes off
! 1124:
! 1125: */
! 1126:
! 1127:
! 1128:
! 1129: static void
! 1130:
! 1131: itimer_prof_me(p)
! 1132:
! 1133: PROC *p;
! 1134:
! 1135: {
! 1136:
! 1137: PROC *real_curproc;
! 1138:
! 1139: long timeleft;
! 1140:
! 1141:
! 1142:
! 1143: real_curproc = curproc;
! 1144:
! 1145: curproc = p;
! 1146:
! 1147: timeleft = p->itimer[ITIMER_PROF].reqtime
! 1148:
! 1149: - (p->usrtime - p->itimer[ITIMER_PROF].startusrtime);
! 1150:
! 1151: if (timeleft > 0) {
! 1152:
! 1153: p->itimer[ITIMER_PROF].timeout =
! 1154:
! 1155: addtimeout(timeleft, itimer_prof_me);
! 1156:
! 1157: } else {
! 1158:
! 1159: timeleft = p->itimer[ITIMER_PROF].interval;
! 1160:
! 1161: if (timeleft == 0) {
! 1162:
! 1163: p->itimer[ITIMER_PROF].timeout = 0;
! 1164:
! 1165: } else {
! 1166:
! 1167: p->itimer[ITIMER_PROF].reqtime = timeleft;
! 1168:
! 1169: p->itimer[ITIMER_PROF].startsystime = p->systime;
! 1170:
! 1171: p->itimer[ITIMER_PROF].startusrtime = p->usrtime;
! 1172:
! 1173: p->itimer[ITIMER_PROF].timeout =
! 1174:
! 1175: addtimeout(timeleft, itimer_prof_me);
! 1176:
! 1177: }
! 1178:
! 1179: post_sig(p, SIGPROF);
! 1180:
! 1181: }
! 1182:
! 1183: curproc = real_curproc;
! 1184:
! 1185: }
! 1186:
! 1187:
! 1188:
! 1189: /*
! 1190:
! 1191: * t_setitimer(which, interval, value, ointerval, ovalue):
! 1192:
! 1193: * schedule an interval timer
! 1194:
! 1195: * which is ITIMER_REAL (0) for SIGALRM, ITIMER_VIRTUAL (1) for SIGVTALRM,
! 1196:
! 1197: * or ITIMER_PROF (2) for SIGPROF.
! 1198:
! 1199: * the rest of the parameters are pointers to millisecond values.
! 1200:
! 1201: * interval is the value to which the timer will be reset
! 1202:
! 1203: * value is the current timer value
! 1204:
! 1205: * ointerval and ovalue are the previous values
! 1206:
! 1207: */
! 1208:
! 1209:
! 1210:
! 1211: long ARGS_ON_STACK
! 1212:
! 1213: t_setitimer(which, interval, value, ointerval, ovalue)
! 1214:
! 1215: int which;
! 1216:
! 1217: long *interval;
! 1218:
! 1219: long *value;
! 1220:
! 1221: long *ointerval;
! 1222:
! 1223: long *ovalue;
! 1224:
! 1225: {
! 1226:
! 1227: long oldtimer;
! 1228:
! 1229: TIMEOUT *t;
! 1230:
! 1231: void (*handler)() = 0;
! 1232:
! 1233: long tmpold;
! 1234:
! 1235:
! 1236:
! 1237: if ((which != ITIMER_REAL) && (which != ITIMER_VIRTUAL)
! 1238:
! 1239: && (which != ITIMER_PROF)) {
! 1240:
! 1241: return EINVFN;
! 1242:
! 1243: }
! 1244:
! 1245:
! 1246:
! 1247: /* ensure that any addresses specified by the calling process are in that
! 1248:
! 1249: process's address space
! 1250:
! 1251: */
! 1252:
! 1253: if ((interval && (!(valid_address((long) interval))))
! 1254:
! 1255: || (value && (!(valid_address((long) value))))
! 1256:
! 1257: || (ointerval && (!(valid_address((long) ointerval))))
! 1258:
! 1259: || (ovalue && (!(valid_address((long) ovalue))))) {
! 1260:
! 1261: return EIMBA;
! 1262:
! 1263: }
! 1264:
! 1265:
! 1266:
! 1267: /* see how many milliseconds there were to the timeout */
! 1268:
! 1269: oldtimer = 0;
! 1270:
! 1271:
! 1272:
! 1273: if (curproc->itimer[which].timeout) {
! 1274:
! 1275: for (t = tlist; t; t = t->next) {
! 1276:
! 1277: oldtimer += t->when;
! 1278:
! 1279: if (t == curproc->itimer[which].timeout)
! 1280:
! 1281: goto foundtimer;
! 1282:
! 1283: }
! 1284:
! 1285: DEBUG(("Tsetitimer: old timer not found!"));
! 1286:
! 1287: oldtimer = 0;
! 1288:
! 1289: foundtimer:
! 1290:
! 1291: ;
! 1292:
! 1293: }
! 1294:
! 1295:
! 1296:
! 1297: if (ointerval)
! 1298:
! 1299: *ointerval = curproc->itimer[which].interval;
! 1300:
! 1301: if (ovalue) {
! 1302:
! 1303: if (which == ITIMER_REAL) {
! 1304:
! 1305: *ovalue = oldtimer;
! 1306:
! 1307: } else {
! 1308:
! 1309: tmpold = curproc->itimer[which].reqtime
! 1310:
! 1311: - (curproc->systime - curproc->itimer[which].startusrtime);
! 1312:
! 1313: if (which == ITIMER_PROF)
! 1314:
! 1315: tmpold -=
! 1316:
! 1317: (curproc->systime - curproc->itimer[which].startsystime);
! 1318:
! 1319: if (tmpold <= 0)
! 1320:
! 1321: tmpold = 0;
! 1322:
! 1323: *ovalue = tmpold;
! 1324:
! 1325: }
! 1326:
! 1327: }
! 1328:
! 1329: if (interval)
! 1330:
! 1331: curproc->itimer[which].interval = *interval;
! 1332:
! 1333: if (value) {
! 1334:
! 1335: /* cancel old timer */
! 1336:
! 1337: if (curproc->itimer[which].timeout)
! 1338:
! 1339: canceltimeout(curproc->itimer[which].timeout);
! 1340:
! 1341: curproc->itimer[which].timeout = 0;
! 1342:
! 1343:
! 1344:
! 1345: /* add a new timer, to occur in x milliseconds */
! 1346:
! 1347: if (*value) {
! 1348:
! 1349: curproc->itimer[which].reqtime = *value;
! 1350:
! 1351: curproc->itimer[which].startsystime =
! 1352:
! 1353: curproc->systime;
! 1354:
! 1355: curproc->itimer[which].startusrtime =
! 1356:
! 1357: curproc->usrtime;
! 1358:
! 1359: switch (which) {
! 1360:
! 1361: case ITIMER_REAL:
! 1362:
! 1363: handler = itimer_real_me;
! 1364:
! 1365: break;
! 1366:
! 1367: case ITIMER_VIRTUAL:
! 1368:
! 1369: handler = itimer_virtual_me;
! 1370:
! 1371: break;
! 1372:
! 1373: case ITIMER_PROF:
! 1374:
! 1375: handler = itimer_prof_me;
! 1376:
! 1377: break;
! 1378:
! 1379: default:
! 1380:
! 1381: break;
! 1382:
! 1383: }
! 1384:
! 1385: curproc->itimer[which].timeout =
! 1386:
! 1387: addtimeout(*value, handler);
! 1388:
! 1389: }
! 1390:
! 1391: else
! 1392:
! 1393: curproc->itimer[which].timeout = 0;
! 1394:
! 1395: }
! 1396:
! 1397: return 0;
! 1398:
! 1399: }
! 1400:
! 1401:
! 1402:
1.1 root 1403: /*
1404:
1405: * sysconf(which): returns information about system configuration.
1406:
1407: * "which" specifies which aspect of the system configuration is to
1408:
1409: * be returned:
1410:
1411: * -1 max. value of "which" allowed
1412:
1413: * 0 max. number of memory regions per proc
1414:
1415: * 1 max. length of Pexec() execution string {ARG_MAX}
1416:
1417: * 2 max. number of open files per process {OPEN_MAX}
1418:
1.1.1.6 ! root 1419: * 3 number of supplementary group id's {NGROUPS_MAX}
1.1 root 1420:
1421: * 4 max. number of processes per uid {CHILD_MAX}
1422:
1423: *
1424:
1425: * unlimited values (e.g. CHILD_MAX) are returned as 0x7fffffffL
1426:
1427: *
1428:
1429: * See also Dpathconf() in dosdir.c.
1430:
1431: */
1432:
1433:
1434:
1.1.1.2 root 1435: long ARGS_ON_STACK
1.1 root 1436:
1437: s_ysconf(which)
1438:
1439: int which;
1440:
1441: {
1442:
1443: if (which == -1)
1444:
1445: return 4;
1446:
1447:
1448:
1449: switch(which) {
1450:
1451: case 0:
1452:
1453: return UNLIMITED;
1454:
1455: case 1:
1456:
1457: return 126;
1458:
1459: case 2:
1460:
1461: return MAX_OPEN;
1462:
1463: case 3:
1464:
1.1.1.6 ! root 1465: return NGROUPS_MAX;
1.1 root 1466:
1467: case 4:
1468:
1469: return UNLIMITED;
1470:
1471: default:
1472:
1473: return EINVFN;
1474:
1475: }
1476:
1477: }
1478:
1479:
1480:
1481: /*
1482:
1.1.1.3 root 1483: * Salert: send an ALERT message to the user, via the same mechanism
1484:
1485: * the kernel does (i.e. u:\pipe\alert, if it's available
1486:
1487: */
1488:
1489:
1490:
1491: long ARGS_ON_STACK
1492:
1493: s_alert(str)
1494:
1495: char *str;
1496:
1497: {
1498:
1499: /* how's this for confusing code? _ALERT tries to format the
1500:
1501: * string as an alert box; if it fails, we let the full-fledged
1502:
1503: * ALERT function (which will try _ALERT, and fail again)
1504:
1505: * print the alert to the debugging device
1506:
1507: */
1508:
1509: if (_ALERT(str) == 0)
1510:
1511: ALERT(str);
1512:
1513: return 0;
1514:
1515: }
1516:
1517:
1518:
1519: /*
1520:
1.1.1.6 ! root 1521: * Suptime: get time in seconds since boot and current load averages from
! 1522:
! 1523: * kernel.
! 1524:
! 1525: */
! 1526:
! 1527:
! 1528:
! 1529: #include "loadave.h"
! 1530:
! 1531:
! 1532:
! 1533: long ARGS_ON_STACK
! 1534:
! 1535: s_uptime(cur_uptime, loadaverage)
! 1536:
! 1537: unsigned long *cur_uptime;
! 1538:
! 1539: unsigned long loadaverage[3];
! 1540:
! 1541: {
! 1542:
! 1543: *cur_uptime = uptime;
! 1544:
! 1545: loadaverage[0] = avenrun[0];
! 1546:
! 1547: loadaverage[1] = avenrun[1];
! 1548:
! 1549: loadaverage[2] = avenrun[2];
! 1550:
! 1551:
! 1552:
! 1553: return 0;
! 1554:
! 1555: }
! 1556:
! 1557:
! 1558:
! 1559: /*
! 1560:
1.1 root 1561: * routine for initializing DOS
1562:
1563: *
1564:
1565: * NOTE: before adding new functions, check the definition of
1566:
1567: * DOS_MAX at the top of this file to make sure that there
1568:
1569: * is room; if not, increase DOS_MAX.
1570:
1571: */
1572:
1573:
1574:
1575: void
1576:
1577: init_dos()
1578:
1579: {
1580:
1581: /* miscellaneous initialization goes here */
1582:
1583:
1584:
1585: /* dos table initialization */
1586:
1587: dos_tab[0x00] = p_term0;
1588:
1589: dos_tab[0x01] = c_conin;
1590:
1591: dos_tab[0x02] = c_conout;
1592:
1593: dos_tab[0x03] = c_auxin;
1594:
1595: dos_tab[0x04] = c_auxout;
1596:
1597: dos_tab[0x05] = c_prnout;
1598:
1599: dos_tab[0x06] = c_rawio;
1600:
1601: dos_tab[0x07] = c_rawcin;
1602:
1603: dos_tab[0x08] = c_necin;
1604:
1605: dos_tab[0x09] = c_conws;
1606:
1607: dos_tab[0x0a] = c_conrs;
1608:
1609: dos_tab[0x0b] = c_conis;
1610:
1611: dos_tab[0x0e] = d_setdrv;
1612:
1613: dos_tab[0x10] = c_conos;
1614:
1615: dos_tab[0x11] = c_prnos;
1616:
1617: dos_tab[0x12] = c_auxis;
1618:
1619: dos_tab[0x13] = c_auxos;
1620:
1621: dos_tab[0x14] = m_addalt;
1622:
1.1.1.3 root 1623: dos_tab[0x15] = s_realloc;
1624:
1.1 root 1625: dos_tab[0x19] = d_getdrv;
1626:
1627: dos_tab[0x1a] = f_setdta;
1628:
1629: dos_tab[0x20] = s_uper;
1630:
1631: dos_tab[0x2a] = t_getdate;
1632:
1633: dos_tab[0x2b] = t_setdate;
1634:
1635: dos_tab[0x2c] = t_gettime;
1636:
1637: dos_tab[0x2d] = t_settime;
1638:
1639: dos_tab[0x2f] = f_getdta;
1640:
1641: dos_tab[0x30] = s_version;
1642:
1643: dos_tab[0x31] = p_termres;
1644:
1645: dos_tab[0x36] = d_free;
1646:
1647: dos_tab[0x39] = d_create;
1648:
1649: dos_tab[0x3a] = d_delete;
1650:
1651: dos_tab[0x3b] = d_setpath;
1652:
1653: dos_tab[0x3c] = f_create;
1654:
1655: dos_tab[0x3d] = f_open;
1656:
1657: dos_tab[0x3e] = f_close;
1658:
1659: dos_tab[0x3f] = f_read;
1660:
1661: dos_tab[0x40] = f_write;
1662:
1663: dos_tab[0x41] = f_delete;
1664:
1665: dos_tab[0x42] = f_seek;
1666:
1667: dos_tab[0x43] = f_attrib;
1668:
1669: dos_tab[0x44] = m_xalloc;
1670:
1671: dos_tab[0x45] = f_dup;
1672:
1673: dos_tab[0x46] = f_force;
1674:
1675: dos_tab[0x47] = d_getpath;
1676:
1677: dos_tab[0x48] = m_alloc;
1678:
1679: dos_tab[0x49] = m_free;
1680:
1681: dos_tab[0x4a] = m_shrink;
1682:
1683: dos_tab[0x4b] = p_exec;
1684:
1685: dos_tab[0x4c] = p_term;
1686:
1687: dos_tab[0x4e] = f_sfirst;
1688:
1689: dos_tab[0x4f] = f_snext;
1690:
1691: dos_tab[0x56] = f_rename;
1692:
1693: dos_tab[0x57] = f_datime;
1694:
1695: dos_tab[0x5c] = f_lock;
1696:
1697:
1698:
1699: /* MiNT extensions to GEMDOS */
1700:
1701:
1702:
1703: dos_tab[0xff] = s_yield;
1704:
1705: dos_tab[0x100] = f_pipe;
1706:
1707: dos_tab[0x104] = f_cntl;
1708:
1.1.1.2 root 1709: dos_tab[0x105] = f_instat;
1.1 root 1710:
1.1.1.2 root 1711: dos_tab[0x106] = f_outstat;
1.1 root 1712:
1.1.1.2 root 1713: dos_tab[0x107] = f_getchar;
1.1 root 1714:
1.1.1.2 root 1715: dos_tab[0x108] = f_putchar;
1.1 root 1716:
1717: dos_tab[0x109] = p_wait;
1718:
1719: dos_tab[0x10a] = p_nice;
1720:
1721: dos_tab[0x10b] = p_getpid;
1722:
1723: dos_tab[0x10c] = p_getppid;
1724:
1725: dos_tab[0x10d] = p_getpgrp;
1726:
1727: dos_tab[0x10e] = p_setpgrp;
1728:
1729: dos_tab[0x10f] = p_getuid;
1730:
1731: dos_tab[0x110] = p_setuid;
1732:
1733: dos_tab[0x111] = p_kill;
1734:
1735: dos_tab[0x112] = p_signal;
1736:
1737: dos_tab[0x113] = p_vfork;
1738:
1739: dos_tab[0x114] = p_getgid;
1740:
1741: dos_tab[0x115] = p_setgid;
1742:
1.1.1.3 root 1743:
1744:
1.1 root 1745: dos_tab[0x116] = p_sigblock;
1746:
1747: dos_tab[0x117] = p_sigsetmask;
1748:
1749: dos_tab[0x118] = p_usrval;
1750:
1751: dos_tab[0x119] = p_domain;
1752:
1753: dos_tab[0x11a] = p_sigreturn;
1754:
1755: dos_tab[0x11b] = p_fork;
1756:
1757: dos_tab[0x11c] = p_wait3;
1758:
1759: dos_tab[0x11d] = f_select;
1760:
1761: dos_tab[0x11e] = p_rusage;
1762:
1763: dos_tab[0x11f] = p_setlimit;
1764:
1765: dos_tab[0x120] = t_alarm;
1766:
1767: dos_tab[0x121] = p_pause;
1768:
1769: dos_tab[0x122] = s_ysconf;
1770:
1771: dos_tab[0x123] = p_sigpending;
1772:
1773: dos_tab[0x124] = d_pathconf;
1774:
1775: dos_tab[0x125] = p_msg;
1776:
1777: dos_tab[0x126] = f_midipipe;
1778:
1779: dos_tab[0x127] = p_renice;
1780:
1781: dos_tab[0x128] = d_opendir;
1782:
1783: dos_tab[0x129] = d_readdir;
1784:
1785: dos_tab[0x12a] = d_rewind;
1786:
1787: dos_tab[0x12b] = d_closedir;
1788:
1789: dos_tab[0x12c] = f_xattr;
1790:
1791: dos_tab[0x12d] = f_link;
1792:
1793: dos_tab[0x12e] = f_symlink;
1794:
1795: dos_tab[0x12f] = f_readlink;
1796:
1797: dos_tab[0x130] = d_cntl;
1798:
1799: dos_tab[0x131] = f_chown;
1800:
1801: dos_tab[0x132] = f_chmod;
1802:
1803: dos_tab[0x133] = p_umask;
1804:
1805: dos_tab[0x134] = p_semaphore;
1806:
1807: dos_tab[0x135] = d_lock;
1808:
1809: dos_tab[0x136] = p_sigpause;
1810:
1811: dos_tab[0x137] = p_sigaction;
1812:
1813: dos_tab[0x138] = p_geteuid;
1814:
1815: dos_tab[0x139] = p_getegid;
1816:
1.1.1.2 root 1817: dos_tab[0x13a] = p_waitpid;
1818:
1819: dos_tab[0x13b] = d_getcwd;
1820:
1.1.1.3 root 1821: dos_tab[0x13c] = s_alert;
1822:
1.1.1.5 root 1823: dos_tab[0x13d] = t_malarm;
1824:
1.1.1.6 ! root 1825: dos_tab[0x13e] = p_sigintr;
! 1826:
! 1827: dos_tab[0x13f] = s_uptime;
! 1828:
! 1829: dos_tab[0x142] = d_xreaddir;
! 1830:
! 1831: dos_tab[0x143] = p_seteuid;
! 1832:
! 1833: dos_tab[0x144] = p_setegid;
! 1834:
! 1835: dos_tab[0x145] = p_getauid;
! 1836:
! 1837: dos_tab[0x146] = p_setauid;
! 1838:
! 1839: dos_tab[0x147] = p_getgroups;
! 1840:
! 1841: dos_tab[0x148] = p_setgroups;
! 1842:
! 1843: dos_tab[0x149] = t_setitimer;
! 1844:
! 1845:
! 1846:
! 1847: /* 0x14a-0x151 reserved */
! 1848:
! 1849:
! 1850:
! 1851: dos_tab[0x152] = d_readlabel;
! 1852:
! 1853: dos_tab[0x153] = d_writelabel;
! 1854:
1.1 root 1855: }
1856:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.