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