|
|
1.1 root 1: /*
2:
1.1.1.3 ! root 3: Copyright 1991,1992 Eric R. Smith.
! 4:
! 5: Copyright 1992 Atari Corporation.
! 6:
! 7: All rights reserved.
1.1 root 8:
9: */
10:
11:
12:
13: /* PROC pseudo-filesystem routines */
14:
15: /* basically just to allow 'ls -l X:' to give a list of active processes
16:
17: * some things to note:
18:
19: * process names are given as name.XXX, where 'XXX' is the pid of the
20:
21: * process
22:
23: * process attributes depend on the run queue as follows:
24:
25: * RUNNING: 0x00 (normal)
26:
27: * READY: 0x01 (read-only)
28:
29: * WAIT: 0x20 (archive bit)
30:
31: * IOBOUND: 0x21 (archive bit+read-only)
32:
33: * ZOMBIE: 0x22 (archive+hidden)
34:
35: * TSR: 0x02 (hidden)
36:
37: * STOP: 0x24 (archive bit+system)
38:
39: * the general principle is: inactive processes have the archive bit (0x20)
40:
41: * set, terminated processes have the hidden bit (0x02) set, stopped processes
42:
43: * have the system bit (0x04) set, and the read-only bit is used to
44:
45: * otherwise distinguish states (which is unfortunate, since it would be
46:
47: * nice if this bit corresponded with file permissions).
48:
49: */
50:
51:
52:
53: #include "mint.h"
54:
55:
56:
57:
58:
1.1.1.2 root 59: static long ARGS_ON_STACK proc_root P_((int drv, fcookie *fc));
1.1 root 60:
1.1.1.2 root 61: static long ARGS_ON_STACK proc_lookup P_((fcookie *dir, const char *name, fcookie *fc));
1.1 root 62:
1.1.1.2 root 63: static long ARGS_ON_STACK proc_getxattr P_((fcookie *fc, XATTR *xattr));
1.1 root 64:
1.1.1.2 root 65: static long ARGS_ON_STACK proc_chattr P_((fcookie *fc, int attrib));
1.1 root 66:
1.1.1.2 root 67: static long ARGS_ON_STACK proc_chown P_((fcookie *fc, int uid, int gid));
1.1 root 68:
1.1.1.2 root 69: static long ARGS_ON_STACK proc_chmode P_((fcookie *fc, unsigned mode));
1.1 root 70:
1.1.1.2 root 71: static long ARGS_ON_STACK proc_rmdir P_((fcookie *dir, const char *name));
1.1 root 72:
1.1.1.2 root 73: static long ARGS_ON_STACK proc_remove P_((fcookie *dir, const char *name));
1.1 root 74:
1.1.1.3 ! root 75: static long ARGS_ON_STACK proc_getname P_((fcookie *root, fcookie *dir, char *pathname,
! 76:
! 77: int size));
1.1 root 78:
1.1.1.2 root 79: static long ARGS_ON_STACK proc_rename P_((fcookie *olddir, char *oldname,
1.1 root 80:
81: fcookie *newdir, const char *newname));
82:
1.1.1.2 root 83: static long ARGS_ON_STACK proc_opendir P_((DIR *dirh, int flags));
1.1 root 84:
1.1.1.2 root 85: static long ARGS_ON_STACK proc_readdir P_((DIR *dirh, char *nm, int nmlen, fcookie *));
1.1 root 86:
1.1.1.2 root 87: static long ARGS_ON_STACK proc_rewinddir P_((DIR *dirh));
1.1 root 88:
1.1.1.2 root 89: static long ARGS_ON_STACK proc_closedir P_((DIR *dirh));
1.1 root 90:
1.1.1.2 root 91: static long ARGS_ON_STACK proc_pathconf P_((fcookie *dir, int which));
1.1 root 92:
1.1.1.2 root 93: static long ARGS_ON_STACK proc_dfree P_((fcookie *dir, long *buf));
1.1 root 94:
1.1.1.2 root 95: static DEVDRV * ARGS_ON_STACK proc_getdev P_((fcookie *fc, long *devsp));
1.1 root 96:
97:
98:
1.1.1.2 root 99: static long ARGS_ON_STACK proc_open P_((FILEPTR *f));
1.1 root 100:
1.1.1.2 root 101: static long ARGS_ON_STACK proc_write P_((FILEPTR *f, const char *buf, long bytes));
1.1 root 102:
1.1.1.2 root 103: static long ARGS_ON_STACK proc_read P_((FILEPTR *f, char *buf, long bytes));
1.1 root 104:
1.1.1.2 root 105: static long ARGS_ON_STACK proc_lseek P_((FILEPTR *f, long where, int whence));
1.1 root 106:
1.1.1.2 root 107: static long ARGS_ON_STACK proc_ioctl P_((FILEPTR *f, int mode, void *buf));
1.1 root 108:
1.1.1.2 root 109: static long ARGS_ON_STACK proc_datime P_((FILEPTR *f, short *time, int rwflag));
1.1 root 110:
1.1.1.2 root 111: static long ARGS_ON_STACK proc_close P_((FILEPTR *f, int pid));
1.1 root 112:
113:
114:
115: /* dummy routines from biosfs.c */
116:
1.1.1.2 root 117: extern long ARGS_ON_STACK null_select P_((FILEPTR *f, long p, int mode));
1.1 root 118:
1.1.1.2 root 119: extern void ARGS_ON_STACK null_unselect P_((FILEPTR *f, long p, int mode));
1.1 root 120:
121:
122:
123: static PROC * name2proc P_((const char *name));
124:
125:
126:
127:
128:
129: DEVDRV proc_device = {
130:
131: proc_open, proc_write, proc_read, proc_lseek, proc_ioctl, proc_datime,
132:
133: proc_close, null_select, null_unselect
134:
135: };
136:
137:
138:
139: FILESYS proc_filesys = {
140:
141: (FILESYS *)0,
142:
143: 0,
144:
145: proc_root,
146:
147: proc_lookup, nocreat, proc_getdev, proc_getxattr,
148:
149: proc_chattr, proc_chown, proc_chmode,
150:
151: nomkdir, proc_rmdir, proc_remove, proc_getname, proc_rename,
152:
153: proc_opendir, proc_readdir, proc_rewinddir, proc_closedir,
154:
155: proc_pathconf, proc_dfree,
156:
157: nowritelabel, noreadlabel, nosymlink, noreadlink, nohardlink,
158:
159: nofscntl, nodskchng
160:
161: };
162:
163:
164:
1.1.1.2 root 165: long ARGS_ON_STACK
1.1 root 166:
167: proc_root(drv, fc)
168:
169: int drv;
170:
171: fcookie *fc;
172:
173: {
174:
175: if (drv == PROCDRV) {
176:
177: fc->fs = &proc_filesys;
178:
179: fc->dev = drv;
180:
181: fc->index = 0L;
182:
183: return 0;
184:
185: }
186:
187: fc->fs = 0;
188:
189: return EINTRN;
190:
191: }
192:
193:
194:
195: static PROC *
196:
197: name2proc(name)
198:
199: const char *name;
200:
201: {
202:
203: const char *pstr;
204:
205: char c;
206:
207: int i;
208:
209:
210:
211: pstr = name;
212:
213: while ( (c = *name++) != 0) {
214:
215: if (c == '.')
216:
217: pstr = name;
218:
219: }
220:
221: if (!isdigit(*pstr) && *pstr != '-')
222:
223: return 0;
224:
1.1.1.2 root 225: i = (int)atol(pstr);
1.1 root 226:
227: if (i == -1)
228:
229: return curproc;
230:
231: else if (i == -2)
232:
233: i = curproc->ppid;
234:
235: return pid2proc(i);
236:
237: }
238:
239:
240:
1.1.1.2 root 241: static long ARGS_ON_STACK
1.1 root 242:
243: proc_lookup(dir, name, fc)
244:
245: fcookie *dir;
246:
247: const char *name;
248:
249: fcookie *fc;
250:
251: {
252:
253: PROC *p;
254:
255:
256:
257: if (dir->index != 0) {
258:
1.1.1.2 root 259: DEBUG(("proc_lookup: bad directory"));
1.1 root 260:
261: return EPTHNF;
262:
263: }
264:
265:
266:
267: /* special case: an empty name in a directory means that directory */
268:
269: /* so does "." */
270:
271: if (!*name || (name[0] == '.' && name[1] == 0)) {
272:
273: *fc = *dir;
274:
275: return 0;
276:
277: }
278:
279:
280:
281: /* another special case: ".." could be a mount point */
282:
283: if (!strcmp(name, "..")) {
284:
285: *fc = *dir;
286:
287: return EMOUNT;
288:
289: }
290:
291:
292:
1.1.1.2 root 293: if (0 == (p = name2proc(name))) {
1.1 root 294:
1.1.1.2 root 295: DEBUG(("proc_lookup: name not found"));
1.1 root 296:
297: return EFILNF;
298:
299: } else {
300:
301: fc->index = (long)p;
302:
303: fc->fs = &proc_filesys;
304:
305: fc->dev = PROC_BASE_DEV | p->pid;
306:
307: }
308:
309: return 0;
310:
311: }
312:
313:
314:
315: static int p_attr[NUM_QUEUES] = { /* attributes corresponding to queues */
316:
317: 0, /* "RUNNING" */
318:
319: 0x01, /* "READY" */
320:
321: 0x20, /* "WAITING" */
322:
323: 0x21, /* "IOBOUND" */
324:
325: 0x22, /* "ZOMBIE" */
326:
327: 0x02, /* "TSR" */
328:
329: 0x24, /* "STOPPED" */
330:
331: 0x21 /* "SELECT" (same as IOBOUND) */
332:
333: };
334:
335:
336:
1.1.1.2 root 337: static long ARGS_ON_STACK
1.1 root 338:
339: proc_getxattr(fc, xattr)
340:
341: fcookie *fc;
342:
343: XATTR *xattr;
344:
345: {
346:
347: PROC *p;
348:
349: extern int proctime, procdate; /* see dosmem.c */
350:
351:
352:
353: xattr->blksize = 1;
354:
355: if (fc->index == 0) {
356:
357: /* the root directory */
358:
359: xattr->index = 0;
360:
361: xattr->dev = PROCDRV;
362:
363: xattr->nlink = 1;
364:
365: xattr->uid = xattr->gid = 0;
366:
367: xattr->size = xattr->nblocks = 0;
368:
369: xattr->mtime = xattr->atime = xattr->ctime = proctime;
370:
371: xattr->mdate = xattr->adate = xattr->cdate = procdate;
372:
373: xattr->mode = S_IFDIR | DEFAULT_DIRMODE;
374:
375: xattr->attr = FA_DIR;
376:
377: return 0;
378:
379: }
380:
381:
382:
383: p = (PROC *)fc->index;
384:
385: xattr->index = p->pid;
386:
387: xattr->dev = PROC_BASE_DEV | p->pid;
388:
389: xattr->nlink = 1;
390:
391: xattr->uid = p->ruid; xattr->gid = p->rgid;
392:
393: xattr->size = xattr->nblocks = memused(p);
394:
395: xattr->mtime = xattr->ctime = xattr->atime = p->starttime;
396:
397: xattr->mdate = xattr->cdate = xattr->adate = p->startdate;
398:
399: xattr->mode = S_IMEM | S_IRUSR | S_IWUSR;
400:
401: xattr->attr = p_attr[p->wait_q];
402:
403: return 0;
404:
405: }
406:
407:
408:
1.1.1.2 root 409: static long ARGS_ON_STACK
1.1 root 410:
411: proc_chattr(fc, attrib)
412:
413: fcookie *fc;
414:
415: int attrib;
416:
417: {
418:
1.1.1.2 root 419: UNUSED(fc); UNUSED(attrib);
420:
421:
422:
1.1 root 423: return EACCDN;
424:
425: }
426:
427:
428:
1.1.1.2 root 429: static long ARGS_ON_STACK
1.1 root 430:
431: proc_chown(fc, uid, gid)
432:
433: fcookie *fc;
434:
435: int uid, gid;
436:
437: {
438:
1.1.1.2 root 439: UNUSED(fc); UNUSED(uid); UNUSED(gid);
440:
1.1 root 441: return EINVFN;
442:
443: }
444:
445:
446:
1.1.1.2 root 447: static long ARGS_ON_STACK
1.1 root 448:
449: proc_chmode(fc, mode)
450:
451: fcookie *fc;
452:
453: unsigned mode;
454:
455: {
456:
1.1.1.2 root 457: UNUSED(fc); UNUSED(mode);
458:
1.1 root 459: return EINVFN;
460:
461: }
462:
463:
464:
1.1.1.2 root 465: static long ARGS_ON_STACK
1.1 root 466:
467: proc_rmdir(dir, name)
468:
469: fcookie *dir;
470:
471: const char *name;
472:
473: {
474:
1.1.1.2 root 475: UNUSED(dir); UNUSED(name);
476:
1.1 root 477: return EPTHNF;
478:
479: }
480:
481:
482:
1.1.1.2 root 483: static long ARGS_ON_STACK
1.1 root 484:
485: proc_remove(dir, name)
486:
487: fcookie *dir;
488:
489: const char *name;
490:
491: {
492:
493: PROC *p;
494:
495:
496:
497: if (dir->index != 0)
498:
499: return EPTHNF;
500:
501: p = name2proc(name);
502:
503: if (!p)
504:
505: return EFILNF;
506:
507:
508:
509: post_sig(p, SIGTERM);
510:
511: check_sigs(); /* it might have been us */
512:
513: return 0;
514:
515: }
516:
517:
518:
1.1.1.2 root 519: static long ARGS_ON_STACK
1.1 root 520:
1.1.1.3 ! root 521: proc_getname(root, dir, pathname, size)
1.1 root 522:
523: fcookie *root, *dir; char *pathname;
524:
1.1.1.3 ! root 525: int size;
! 526:
1.1 root 527: {
528:
529: PROC *p;
530:
531:
532:
1.1.1.2 root 533: UNUSED(root);
534:
1.1.1.3 ! root 535: /* BUG: we ought to look at size */
! 536:
! 537: UNUSED(size);
! 538:
1.1.1.2 root 539:
540:
1.1 root 541: if (dir->index == 0)
542:
543: *pathname = 0;
544:
545: else {
546:
547: p = (PROC *)dir->index;
548:
549: ksprintf(pathname, "%s.03d", p->name, p->pid);
550:
551: }
552:
553: return 0;
554:
555: }
556:
557:
558:
1.1.1.2 root 559: static long ARGS_ON_STACK
1.1 root 560:
561: proc_rename(olddir, oldname, newdir, newname)
562:
563: fcookie *olddir;
564:
565: char *oldname;
566:
567: fcookie *newdir;
568:
569: const char *newname;
570:
571: {
572:
573: PROC *p;
574:
575: int i;
576:
577:
578:
579: if (olddir->index != 0 || newdir->index != 0)
580:
581: return EPTHNF;
582:
1.1.1.2 root 583: if ((p = name2proc(oldname)) == 0)
1.1 root 584:
585: return EFILNF;
586:
587:
588:
589: oldname = p->name;
590:
591: for (i = 0; i < PNAMSIZ; i++) {
592:
593: if (*newname == 0 || *newname == '.') {
594:
595: *oldname = 0; break;
596:
597: }
598:
599: *oldname++ = *newname++;
600:
601: }
602:
603: return 0;
604:
605: }
606:
607:
608:
1.1.1.2 root 609: static long ARGS_ON_STACK
1.1 root 610:
611: proc_opendir(dirh, flags)
612:
613: DIR *dirh;
614:
615: int flags;
616:
617: {
618:
1.1.1.2 root 619: UNUSED(flags);
620:
621:
622:
1.1 root 623: dirh->index = 0;
624:
625: return 0;
626:
627: }
628:
629:
630:
1.1.1.2 root 631: static long ARGS_ON_STACK
1.1 root 632:
633: proc_readdir(dirh, name, namelen, fc)
634:
635: DIR *dirh;
636:
637: char *name;
638:
639: int namelen;
640:
641: fcookie *fc;
642:
643: {
644:
645: int i;
646:
647: int giveindex = (dirh->flags == 0);
648:
649: PROC *p;
650:
651:
652:
653: do {
654:
655: i = dirh->index++;
656:
657: /* BUG: we shouldn't have the magic number "1000" for maximum proc pid */
658:
659: if (i >= 1000) {
660:
661: p = 0;
662:
663: break;
664:
665: }
666:
667: p = pid2proc(i);
668:
669: } while (!p);
670:
671:
672:
673: if (!p)
674:
675: return ENMFIL;
676:
677:
678:
679: fc->index = (long)p;
680:
681: fc->fs = &proc_filesys;
682:
683: fc->dev = PROC_BASE_DEV | p->pid;
684:
685:
686:
687: if (giveindex) {
688:
1.1.1.2 root 689: namelen -= (int)sizeof(long);
1.1 root 690:
691: if (namelen <= 0) return ERANGE;
692:
693: *((long *)name) = (long)p->pid;
694:
695: name += sizeof(long);
696:
697: }
698:
699: if (namelen < strlen(p->name) + 5)
700:
701: return ENAMETOOLONG;
702:
703:
704:
705: ksprintf(name, "%s.%03d", p->name, p->pid);
706:
707: return 0;
708:
709: }
710:
711:
712:
1.1.1.2 root 713: static long ARGS_ON_STACK
1.1 root 714:
715: proc_rewinddir(dirh)
716:
717: DIR *dirh;
718:
719: {
720:
721: dirh->index = 0;
722:
723: return 0;
724:
725: }
726:
727:
728:
1.1.1.2 root 729: static long ARGS_ON_STACK
1.1 root 730:
731: proc_closedir(dirh)
732:
733: DIR *dirh;
734:
735: {
736:
1.1.1.2 root 737: UNUSED(dirh);
738:
1.1 root 739: return 0;
740:
741: }
742:
1.1.1.2 root 743: static long ARGS_ON_STACK
1.1 root 744:
745: proc_pathconf(dir, which)
746:
747: fcookie *dir;
748:
749: int which;
750:
751: {
752:
1.1.1.2 root 753: UNUSED(dir);
754:
755:
756:
1.1 root 757: switch(which) {
758:
759: case -1:
760:
761: return DP_MAXREQ;
762:
763: case DP_IOPEN:
764:
765: return UNLIMITED; /* no internal limit on open files */
766:
767: case DP_MAXLINKS:
768:
769: return 1; /* we don't have hard links */
770:
771: case DP_PATHMAX:
772:
773: return PATH_MAX; /* max. path length */
774:
775: case DP_NAMEMAX:
776:
777: return PNAMSIZ; /* max. length of individual name */
778:
779: case DP_ATOMIC:
780:
781: return UNLIMITED; /* all writes are atomic */
782:
783: case DP_TRUNC:
784:
785: return DP_DOSTRUNC; /* file names are truncated to 8.3 */
786:
787: case DP_CASE:
788:
789: return DP_CASEINSENS; /* case preserved, but ignored */
790:
791: default:
792:
793: return EINVFN;
794:
795: }
796:
797: }
798:
799:
800:
1.1.1.2 root 801: static long ARGS_ON_STACK
1.1 root 802:
803: proc_dfree(dir, buf)
804:
805: fcookie *dir;
806:
807: long *buf;
808:
809: {
810:
811: long size;
812:
813: /* "sector" size is the size of the smallest amount of memory that can be
814:
815: allocated. see mem.h for the definition of ROUND
816:
817: */
818:
819: long secsiz = ROUND(1);
820:
821:
822:
1.1.1.2 root 823: UNUSED(dir);
824:
825:
826:
1.1 root 827: size = tot_rsize(core, 0) + tot_rsize(alt, 0);
828:
829: *buf++ = size/secsiz; /* number of free clusters */
830:
831: size = tot_rsize(core, 1) + tot_rsize(alt, 1);
832:
833: *buf++ = size/secsiz; /* total number of clusters */
834:
835: *buf++ = secsiz; /* sector size (bytes) */
836:
1.1.1.2 root 837: *buf = 1; /* cluster size (in sectors) */
1.1 root 838:
839: return 0;
840:
841: }
842:
843:
844:
1.1.1.2 root 845: static DEVDRV * ARGS_ON_STACK
1.1 root 846:
847: proc_getdev(fc, devsp)
848:
849: fcookie *fc;
850:
851: long *devsp;
852:
853: {
854:
855: PROC *p;
856:
857:
858:
859: p = (PROC *)fc->index;
860:
861:
862:
863: *devsp = (long)p;
864:
865: return &proc_device;
866:
867: }
868:
869:
870:
871: /*
872:
873: * PROC device driver
874:
875: */
876:
877:
878:
879: /*
880:
881: * BUG: file locking and the O_SHMODE restrictions are not implemented
882:
883: * for processes
884:
885: */
886:
887:
888:
1.1.1.2 root 889: static long ARGS_ON_STACK
1.1 root 890:
891: proc_open(f)
892:
893: FILEPTR *f;
894:
895: {
896:
1.1.1.2 root 897: UNUSED(f);
898:
899:
900:
1.1 root 901: return 0;
902:
903: }
904:
905:
906:
1.1.1.2 root 907: static long ARGS_ON_STACK
1.1 root 908:
909: proc_write(f, buf, nbytes)
910:
911: FILEPTR *f; const char *buf; long nbytes;
912:
913: {
914:
1.1.1.3 ! root 915: PROC *p = (PROC *)f->devinfo;
! 916:
1.1 root 917: char *where;
918:
919: long bytes_written = 0;
920:
1.1.1.3 ! root 921: int prot_hold;
! 922:
1.1 root 923:
924:
925: where = (char *)f->pos;
926:
927:
928:
1.1.1.3 ! root 929: TRACE(("proc_write to pid %d: %ld bytes to %lx", p->pid, nbytes, where));
! 930:
! 931:
! 932:
! 933: prot_hold = mem_access_for(p, (ulong)where,nbytes);
! 934:
! 935: if (prot_hold == 0) {
! 936:
! 937: DEBUG(("Can't Fwrite that memory: not all the same or not owner."));
! 938:
! 939: return EACCDN;
1.1 root 940:
1.1.1.3 ! root 941: }
! 942:
! 943: if (prot_hold == 1) {
1.1 root 944:
1.1.1.3 ! root 945: DEBUG(("Attempt to Fwrite memory crossing a managed boundary"));
1.1 root 946:
1.1.1.3 ! root 947: return EACCDN;
! 948:
! 949: }
1.1 root 950:
951:
952:
953: while (nbytes-- > 0) {
954:
955: *where++ = *buf++;
956:
957: bytes_written++;
958:
959: }
960:
1.1.1.2 root 961: cpush((void *)f->pos, bytes_written); /* flush cached data */
962:
1.1.1.3 ! root 963:
! 964:
! 965: /* MEMPROT: done with temp mapping (only call if temp'ed above) */
! 966:
! 967: if (prot_hold != -1) prot_temp((ulong)f->pos,nbytes,prot_hold);
! 968:
! 969:
! 970:
1.1 root 971: f->pos += bytes_written;
972:
973: return bytes_written;
974:
975: }
976:
977:
978:
1.1.1.2 root 979: static long ARGS_ON_STACK
1.1 root 980:
981: proc_read(f, buf, nbytes)
982:
983: FILEPTR *f; char *buf; long nbytes;
984:
985: {
986:
1.1.1.3 ! root 987: PROC *p = (PROC *)f->devinfo;
! 988:
1.1 root 989: char *where;
990:
991: long bytes_read = 0;
992:
1.1.1.3 ! root 993: int prot_hold;
! 994:
1.1 root 995:
996:
997: where = (char *)f->pos;
998:
999:
1000:
1.1.1.3 ! root 1001: TRACE(("proc_read from pid %d: %ld bytes from %lx", p->pid, nbytes, where));
! 1002:
! 1003:
! 1004:
! 1005: prot_hold = mem_access_for(p, (ulong)where,nbytes);
! 1006:
! 1007: if (prot_hold == 0) {
! 1008:
! 1009: DEBUG(("Can't Fread that memory: not all the same."));
! 1010:
! 1011: return EACCDN;
! 1012:
! 1013: }
! 1014:
! 1015: if (prot_hold == 1) {
! 1016:
! 1017: DEBUG(("Attempt to Fread memory crossing a managed boundary"));
! 1018:
! 1019: return EACCDN;
! 1020:
! 1021: }
1.1 root 1022:
1023:
1024:
1025: while (nbytes-- > 0) {
1026:
1027: *buf++ = *where++;
1028:
1029: bytes_read++;
1030:
1031: }
1032:
1.1.1.3 ! root 1033:
! 1034:
! 1035: /* MEMPROT: done with temp mapping (only call if temp'ed above) */
! 1036:
! 1037: if (prot_hold != -1) prot_temp((ulong)f->pos,nbytes,prot_hold);
! 1038:
! 1039:
! 1040:
1.1 root 1041: f->pos += bytes_read;
1042:
1043: return bytes_read;
1044:
1045: }
1046:
1047:
1048:
1049: /*
1050:
1051: * proc_ioctl: currently, the only IOCTL's available are:
1052:
1053: * PPROCADDR: get address of PROC structure's "interesting" bits
1054:
1055: * PCTXTSIZE: get the size of the CONTEXT structure
1056:
1057: * PBASEADDR: get address of process basepage
1058:
1059: * PSETFLAGS: set the memory allocation flags (e.g. to malloc from fastram)
1060:
1061: * PGETFLAGS: get the memory allocation flags
1062:
1.1.1.2 root 1063: * PTRACESFLAGS: set the process tracing flags
1064:
1065: * PTRACEGFLAGS: get the process tracing flags
1066:
1067: * PTRACEGO: restart the process (T1=0/T1=0)
1068:
1069: * PTRACEFLOW: restart the process (T1=0/T0=1)
1070:
1071: * PTRACESTEP: restart the process (T1=1/T0=0)
1072:
1073: * PTRACE11: restart the process (T1=1/T0=1)
1074:
1.1 root 1075: */
1076:
1077:
1078:
1.1.1.2 root 1079: static long ARGS_ON_STACK
1.1 root 1080:
1081: proc_ioctl(f, mode, buf)
1082:
1083: FILEPTR *f; int mode; void *buf;
1084:
1085: {
1086:
1087: PROC *p;
1088:
1.1.1.2 root 1089: extern long mcpu; /* in main.c */
1090:
1.1 root 1091:
1092:
1093: p = (PROC *)f->devinfo;
1094:
1095: switch(mode) {
1096:
1097: case PPROCADDR:
1098:
1099: *((long *)buf) = (long)&p->magic;
1100:
1101: return 0;
1102:
1103: case PBASEADDR:
1104:
1105: *((long *)buf) = (long)p->base;
1106:
1107: return 0;
1108:
1109: case PCTXTSIZE:
1110:
1111: *((long *)buf) = sizeof(CONTEXT);
1112:
1113: return 0;
1114:
1115: case PSETFLAGS:
1116:
1.1.1.3 ! root 1117: {
! 1118:
! 1119: int newflags = (ushort)(*(long *)buf);
! 1120:
! 1121: if ((newflags & F_OS_SPECIAL) &&
! 1122:
! 1123: (!(p->memflags & F_OS_SPECIAL))) {
! 1124:
! 1125: /* you're making the process OS_SPECIAL */
! 1126:
! 1127: TRACE(("Fcntl OS_SPECIAL pid %d",p->pid));
! 1128:
! 1129: p->memflags = newflags;
! 1130:
! 1131: mem_prot_special(p);
! 1132:
! 1133: }
! 1134:
1.1 root 1135: /* note: only the low 16 bits are actually used */
1136:
1137: p->memflags = *((long *)buf);
1138:
1139: return 0;
1140:
1.1.1.3 ! root 1141: }
! 1142:
1.1 root 1143: case PGETFLAGS:
1144:
1145: *((long *)buf) = p->memflags;
1146:
1147: return 0;
1148:
1.1.1.2 root 1149: case PTRACESFLAGS:
1150:
1151: if (p->ptracer == curproc || p->ptracer == 0) {
1152:
1153: p->ptraceflags = *(ushort *)buf;
1154:
1155: if (p->ptraceflags == 0) {
1156:
1157: p->ptracer = 0;
1158:
1159: p->ctxt[CURRENT].ptrace = 0;
1160:
1161: p->ctxt[SYSCALL].ptrace = 0;
1162:
1163: }
1164:
1165: else if (p == curproc) {
1166:
1167: p->ptracer = pid2proc(p->ppid);
1168:
1169: } else {
1170:
1171: p->ptracer = curproc;
1172:
1173: }
1174:
1175: } else {
1176:
1177: DEBUG(("proc_ioctl: process already being traced"));
1178:
1179: return EACCDN;
1180:
1181: }
1182:
1183: return 0;
1184:
1185: case PTRACEGFLAGS:
1186:
1187: if (p->ptracer == curproc) {
1188:
1189: *(ushort *)buf = p->ptraceflags;
1190:
1191: return 0;
1192:
1193: } else {
1194:
1195: return EACCDN;
1196:
1197: }
1198:
1199: case PTRACE11:
1200:
1201: return EINVFN;
1202:
1203: case PTRACEFLOW:
1204:
1205: if (mcpu < 20) {
1206:
1207: DEBUG(("proc_ioctl: wrong processor"));
1208:
1209: return EINVFN;
1210:
1211: }
1212:
1213: /* fall through */
1214:
1215: case PTRACEGO:
1216:
1217: case PTRACESTEP:
1218:
1219: if (!p->ptracer) {
1220:
1221: DEBUG(("proc_ioctl(PTRACE): process not being traced"));
1222:
1223: return EACCDN;
1224:
1225: }
1226:
1227: else if (p->wait_q != STOP_Q) {
1228:
1229: DEBUG(("proc_ioctl(PTRACE): process not stopped"));
1230:
1231: return EACCDN;
1232:
1233: }
1234:
1235: else if (p->wait_cond &&
1236:
1237: (1L << ((p->wait_cond >> 8) & 0x1f)) & STOPSIGS) {
1238:
1239: DEBUG(("proc_ioctl(PTRACE): process stopped by job control"));
1240:
1241: return EACCDN;
1242:
1243: }
1244:
1245: p->ctxt[SYSCALL].sr &= 0x3fff; /* clear both trace bits */
1246:
1247: p->ctxt[SYSCALL].sr |= (mode - PTRACEGO) << 14;
1248:
1249: p->sigpending = 0;
1250:
1251: if (buf && *(ushort *)buf != 0) {
1252:
1253: TRACE(("PTRACEGO: sending signal %d to pid %d", *(ushort *)buf, p->pid));
1254:
1255: post_sig(p, *(ushort *)buf);
1256:
1257:
1258:
1259: /* another SIGNULL hack... within check_sigs() we watch for a pending
1260:
1261: * SIGNULL, if we see this then we allow delivery of a signal to the
1262:
1263: * process, rather than telling the parent.
1264:
1265: */
1266:
1267: p->sigpending |= 1L;
1268:
1269: } else {
1270:
1271: TRACE(("PTRACEGO: no signal"));
1272:
1273: }
1274:
1275: /* wake the process up */
1276:
1277: rm_q(p->wait_q, p);
1278:
1279: add_q(READY_Q, p);
1280:
1281: return 0;
1282:
1.1 root 1283: case FIONREAD:
1284:
1285: case FIONWRITE:
1286:
1287: *((long *)buf) = 1L; /* we're always ready for i/o */
1288:
1289: return 0;
1290:
1291: default:
1292:
1.1.1.2 root 1293: DEBUG(("procfs: bad Fcntl command"));
1.1 root 1294:
1295: }
1296:
1297: return EINVFN;
1298:
1299: }
1300:
1301:
1302:
1.1.1.2 root 1303: static long ARGS_ON_STACK
1.1 root 1304:
1305: proc_lseek(f, where, whence)
1306:
1307: FILEPTR *f; long where; int whence;
1308:
1309: {
1310:
1311: switch(whence) {
1312:
1313: case 0:
1314:
1315: f->pos = where;
1316:
1317: break;
1318:
1319: case 1:
1320:
1321: f->pos += where;
1322:
1323: break;
1324:
1325: case 2:
1326:
1327: f->pos = -where;
1328:
1329: break;
1330:
1331: default:
1332:
1333: return EINVFN;
1334:
1335: }
1336:
1337: return f->pos;
1338:
1339: }
1340:
1341:
1342:
1.1.1.2 root 1343: static long ARGS_ON_STACK
1.1 root 1344:
1345: proc_datime(f, timeptr, rwflag)
1346:
1347: FILEPTR *f;
1348:
1349: short *timeptr;
1350:
1351: int rwflag;
1352:
1353: {
1354:
1355: PROC *p;
1356:
1357:
1358:
1359: p = (PROC *)f->devinfo;
1360:
1361: if (rwflag) {
1362:
1363: return EACCDN;
1364:
1365: }
1366:
1367: else {
1368:
1369: *timeptr++ = p->starttime;
1370:
1.1.1.2 root 1371: *timeptr = p->startdate;
1.1 root 1372:
1373: }
1374:
1375: return 0;
1376:
1377: }
1378:
1379:
1380:
1.1.1.2 root 1381: static long ARGS_ON_STACK
1.1 root 1382:
1383: proc_close(f, pid)
1384:
1385: FILEPTR *f;
1386:
1387: int pid;
1388:
1389: {
1390:
1.1.1.2 root 1391: UNUSED(f); UNUSED(pid);
1392:
1.1 root 1393: return 0;
1394:
1395: }
1396:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.