|
|
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:
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:
1.1.1.5 ! root 305: fc->dev = PROC_RDEV_BASE | p->pid;
1.1 root 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:
1.1.1.5 ! root 361: xattr->dev = xattr->rdev = PROCDRV;
1.1 root 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:
1.1.1.5 ! root 387: xattr->dev = xattr->rdev = PROC_RDEV_BASE | p->pid;
1.1 root 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:
1.1.1.4 root 509: /* this check is necessary because the Fdelete code checks for
510:
511: * write permission on the directory, not on individual
512:
513: * files
514:
515: */
516:
517: if (curproc->euid && curproc->ruid != p->ruid) {
518:
519: DEBUG(("proc_remove: wrong user"));
520:
521: return EACCDN;
522:
523: }
524:
1.1 root 525: post_sig(p, SIGTERM);
526:
527: check_sigs(); /* it might have been us */
528:
529: return 0;
530:
531: }
532:
533:
534:
1.1.1.2 root 535: static long ARGS_ON_STACK
1.1 root 536:
1.1.1.3 root 537: proc_getname(root, dir, pathname, size)
1.1 root 538:
539: fcookie *root, *dir; char *pathname;
540:
1.1.1.3 root 541: int size;
542:
1.1 root 543: {
544:
545: PROC *p;
546:
547:
548:
1.1.1.2 root 549: UNUSED(root);
550:
1.1.1.3 root 551: /* BUG: we ought to look at size */
552:
553: UNUSED(size);
554:
1.1.1.2 root 555:
556:
1.1 root 557: if (dir->index == 0)
558:
559: *pathname = 0;
560:
561: else {
562:
563: p = (PROC *)dir->index;
564:
565: ksprintf(pathname, "%s.03d", p->name, p->pid);
566:
567: }
568:
569: return 0;
570:
571: }
572:
573:
574:
1.1.1.2 root 575: static long ARGS_ON_STACK
1.1 root 576:
577: proc_rename(olddir, oldname, newdir, newname)
578:
579: fcookie *olddir;
580:
581: char *oldname;
582:
583: fcookie *newdir;
584:
585: const char *newname;
586:
587: {
588:
589: PROC *p;
590:
591: int i;
592:
593:
594:
595: if (olddir->index != 0 || newdir->index != 0)
596:
597: return EPTHNF;
598:
1.1.1.2 root 599: if ((p = name2proc(oldname)) == 0)
1.1 root 600:
601: return EFILNF;
602:
603:
604:
605: oldname = p->name;
606:
607: for (i = 0; i < PNAMSIZ; i++) {
608:
609: if (*newname == 0 || *newname == '.') {
610:
611: *oldname = 0; break;
612:
613: }
614:
615: *oldname++ = *newname++;
616:
617: }
618:
619: return 0;
620:
621: }
622:
623:
624:
1.1.1.2 root 625: static long ARGS_ON_STACK
1.1 root 626:
627: proc_opendir(dirh, flags)
628:
629: DIR *dirh;
630:
631: int flags;
632:
633: {
634:
1.1.1.2 root 635: UNUSED(flags);
636:
637:
638:
1.1 root 639: dirh->index = 0;
640:
641: return 0;
642:
643: }
644:
645:
646:
1.1.1.2 root 647: static long ARGS_ON_STACK
1.1 root 648:
649: proc_readdir(dirh, name, namelen, fc)
650:
651: DIR *dirh;
652:
653: char *name;
654:
655: int namelen;
656:
657: fcookie *fc;
658:
659: {
660:
661: int i;
662:
663: int giveindex = (dirh->flags == 0);
664:
665: PROC *p;
666:
667:
668:
669: do {
670:
671: i = dirh->index++;
672:
673: /* BUG: we shouldn't have the magic number "1000" for maximum proc pid */
674:
675: if (i >= 1000) {
676:
677: p = 0;
678:
679: break;
680:
681: }
682:
683: p = pid2proc(i);
684:
685: } while (!p);
686:
687:
688:
689: if (!p)
690:
691: return ENMFIL;
692:
693:
694:
695: fc->index = (long)p;
696:
697: fc->fs = &proc_filesys;
698:
1.1.1.5 ! root 699: fc->dev = PROC_RDEV_BASE | p->pid;
1.1 root 700:
701:
702:
703: if (giveindex) {
704:
1.1.1.2 root 705: namelen -= (int)sizeof(long);
1.1 root 706:
707: if (namelen <= 0) return ERANGE;
708:
709: *((long *)name) = (long)p->pid;
710:
711: name += sizeof(long);
712:
713: }
714:
715: if (namelen < strlen(p->name) + 5)
716:
717: return ENAMETOOLONG;
718:
719:
720:
721: ksprintf(name, "%s.%03d", p->name, p->pid);
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_rewinddir(dirh)
732:
733: DIR *dirh;
734:
735: {
736:
737: dirh->index = 0;
738:
739: return 0;
740:
741: }
742:
743:
744:
1.1.1.2 root 745: static long ARGS_ON_STACK
1.1 root 746:
747: proc_closedir(dirh)
748:
749: DIR *dirh;
750:
751: {
752:
1.1.1.2 root 753: UNUSED(dirh);
754:
1.1 root 755: return 0;
756:
757: }
758:
1.1.1.2 root 759: static long ARGS_ON_STACK
1.1 root 760:
761: proc_pathconf(dir, which)
762:
763: fcookie *dir;
764:
765: int which;
766:
767: {
768:
1.1.1.2 root 769: UNUSED(dir);
770:
771:
772:
1.1 root 773: switch(which) {
774:
775: case -1:
776:
777: return DP_MAXREQ;
778:
779: case DP_IOPEN:
780:
781: return UNLIMITED; /* no internal limit on open files */
782:
783: case DP_MAXLINKS:
784:
785: return 1; /* we don't have hard links */
786:
787: case DP_PATHMAX:
788:
789: return PATH_MAX; /* max. path length */
790:
791: case DP_NAMEMAX:
792:
1.1.1.4 root 793: return PNAMSIZ + 4; /* max. length of individual name */
794:
795: /* the "+4" is for the pid: ".123" */
1.1 root 796:
797: case DP_ATOMIC:
798:
799: return UNLIMITED; /* all writes are atomic */
800:
801: case DP_TRUNC:
802:
803: return DP_DOSTRUNC; /* file names are truncated to 8.3 */
804:
805: case DP_CASE:
806:
807: return DP_CASEINSENS; /* case preserved, but ignored */
808:
809: default:
810:
811: return EINVFN;
812:
813: }
814:
815: }
816:
817:
818:
1.1.1.2 root 819: static long ARGS_ON_STACK
1.1 root 820:
821: proc_dfree(dir, buf)
822:
823: fcookie *dir;
824:
825: long *buf;
826:
827: {
828:
829: long size;
830:
831: /* "sector" size is the size of the smallest amount of memory that can be
832:
833: allocated. see mem.h for the definition of ROUND
834:
835: */
836:
837: long secsiz = ROUND(1);
838:
839:
840:
1.1.1.2 root 841: UNUSED(dir);
842:
843:
844:
1.1 root 845: size = tot_rsize(core, 0) + tot_rsize(alt, 0);
846:
847: *buf++ = size/secsiz; /* number of free clusters */
848:
849: size = tot_rsize(core, 1) + tot_rsize(alt, 1);
850:
851: *buf++ = size/secsiz; /* total number of clusters */
852:
853: *buf++ = secsiz; /* sector size (bytes) */
854:
1.1.1.2 root 855: *buf = 1; /* cluster size (in sectors) */
1.1 root 856:
857: return 0;
858:
859: }
860:
861:
862:
1.1.1.2 root 863: static DEVDRV * ARGS_ON_STACK
1.1 root 864:
865: proc_getdev(fc, devsp)
866:
867: fcookie *fc;
868:
869: long *devsp;
870:
871: {
872:
873: PROC *p;
874:
875:
876:
877: p = (PROC *)fc->index;
878:
879:
880:
881: *devsp = (long)p;
882:
883: return &proc_device;
884:
885: }
886:
887:
888:
889: /*
890:
891: * PROC device driver
892:
893: */
894:
895:
896:
897: /*
898:
899: * BUG: file locking and the O_SHMODE restrictions are not implemented
900:
901: * for processes
902:
903: */
904:
905:
906:
1.1.1.2 root 907: static long ARGS_ON_STACK
1.1 root 908:
909: proc_open(f)
910:
911: FILEPTR *f;
912:
913: {
914:
1.1.1.2 root 915: UNUSED(f);
916:
917:
918:
1.1 root 919: return 0;
920:
921: }
922:
923:
924:
1.1.1.2 root 925: static long ARGS_ON_STACK
1.1 root 926:
927: proc_write(f, buf, nbytes)
928:
929: FILEPTR *f; const char *buf; long nbytes;
930:
931: {
932:
1.1.1.3 root 933: PROC *p = (PROC *)f->devinfo;
934:
1.1 root 935: char *where;
936:
937: long bytes_written = 0;
938:
1.1.1.3 root 939: int prot_hold;
940:
1.1 root 941:
942:
943: where = (char *)f->pos;
944:
945:
946:
1.1.1.3 root 947: TRACE(("proc_write to pid %d: %ld bytes to %lx", p->pid, nbytes, where));
948:
949:
950:
951: prot_hold = mem_access_for(p, (ulong)where,nbytes);
952:
953: if (prot_hold == 0) {
954:
955: DEBUG(("Can't Fwrite that memory: not all the same or not owner."));
956:
957: return EACCDN;
1.1 root 958:
1.1.1.3 root 959: }
960:
961: if (prot_hold == 1) {
1.1 root 962:
1.1.1.3 root 963: DEBUG(("Attempt to Fwrite memory crossing a managed boundary"));
1.1 root 964:
1.1.1.3 root 965: return EACCDN;
966:
967: }
1.1 root 968:
969:
970:
1.1.1.5 ! root 971: bytes_written = nbytes;
! 972:
1.1 root 973: while (nbytes-- > 0) {
974:
975: *where++ = *buf++;
976:
977: }
978:
1.1.1.2 root 979: cpush((void *)f->pos, bytes_written); /* flush cached data */
980:
1.1.1.3 root 981:
982:
983: /* MEMPROT: done with temp mapping (only call if temp'ed above) */
984:
1.1.1.5 ! root 985: if (prot_hold != -1) prot_temp((ulong)f->pos,bytes_written,prot_hold);
1.1.1.3 root 986:
987:
988:
1.1 root 989: f->pos += bytes_written;
990:
991: return bytes_written;
992:
993: }
994:
995:
996:
1.1.1.2 root 997: static long ARGS_ON_STACK
1.1 root 998:
999: proc_read(f, buf, nbytes)
1000:
1001: FILEPTR *f; char *buf; long nbytes;
1002:
1003: {
1004:
1.1.1.3 root 1005: PROC *p = (PROC *)f->devinfo;
1006:
1.1 root 1007: char *where;
1008:
1009: long bytes_read = 0;
1010:
1.1.1.3 root 1011: int prot_hold;
1012:
1.1 root 1013:
1014:
1015: where = (char *)f->pos;
1016:
1017:
1018:
1.1.1.3 root 1019: TRACE(("proc_read from pid %d: %ld bytes from %lx", p->pid, nbytes, where));
1020:
1021:
1022:
1023: prot_hold = mem_access_for(p, (ulong)where,nbytes);
1024:
1025: if (prot_hold == 0) {
1026:
1027: DEBUG(("Can't Fread that memory: not all the same."));
1028:
1029: return EACCDN;
1030:
1031: }
1032:
1033: if (prot_hold == 1) {
1034:
1035: DEBUG(("Attempt to Fread memory crossing a managed boundary"));
1036:
1037: return EACCDN;
1038:
1039: }
1.1 root 1040:
1041:
1042:
1.1.1.5 ! root 1043: bytes_read = nbytes;
! 1044:
1.1 root 1045: while (nbytes-- > 0) {
1046:
1047: *buf++ = *where++;
1048:
1049: }
1050:
1.1.1.3 root 1051:
1052:
1053: /* MEMPROT: done with temp mapping (only call if temp'ed above) */
1054:
1.1.1.5 ! root 1055: if (prot_hold != -1) prot_temp((ulong)f->pos,bytes_read,prot_hold);
1.1.1.3 root 1056:
1057:
1058:
1.1 root 1059: f->pos += bytes_read;
1060:
1061: return bytes_read;
1062:
1063: }
1064:
1065:
1066:
1067: /*
1068:
1069: * proc_ioctl: currently, the only IOCTL's available are:
1070:
1071: * PPROCADDR: get address of PROC structure's "interesting" bits
1072:
1073: * PCTXTSIZE: get the size of the CONTEXT structure
1074:
1075: * PBASEADDR: get address of process basepage
1076:
1077: * PSETFLAGS: set the memory allocation flags (e.g. to malloc from fastram)
1078:
1079: * PGETFLAGS: get the memory allocation flags
1080:
1.1.1.2 root 1081: * PTRACESFLAGS: set the process tracing flags
1082:
1083: * PTRACEGFLAGS: get the process tracing flags
1084:
1085: * PTRACEGO: restart the process (T1=0/T1=0)
1086:
1087: * PTRACEFLOW: restart the process (T1=0/T0=1)
1088:
1089: * PTRACESTEP: restart the process (T1=1/T0=0)
1090:
1091: * PTRACE11: restart the process (T1=1/T0=1)
1092:
1.1.1.4 root 1093: * PLOADINFO: get information about the process name and command line
1094:
1.1 root 1095: */
1096:
1097:
1098:
1.1.1.2 root 1099: static long ARGS_ON_STACK
1.1 root 1100:
1101: proc_ioctl(f, mode, buf)
1102:
1103: FILEPTR *f; int mode; void *buf;
1104:
1105: {
1106:
1107: PROC *p;
1108:
1.1.1.2 root 1109: extern long mcpu; /* in main.c */
1110:
1.1.1.5 ! root 1111: short sr;
! 1112:
1.1 root 1113:
1114:
1115: p = (PROC *)f->devinfo;
1116:
1117: switch(mode) {
1118:
1119: case PPROCADDR:
1120:
1121: *((long *)buf) = (long)&p->magic;
1122:
1123: return 0;
1124:
1125: case PBASEADDR:
1126:
1.1.1.5 ! root 1127: if (p == rootproc)
! 1128:
! 1129: *((long *)buf) = (long)_base;
! 1130:
! 1131: else
! 1132:
! 1133: *((long *)buf) = (long)p->base;
1.1 root 1134:
1135: return 0;
1136:
1137: case PCTXTSIZE:
1138:
1139: *((long *)buf) = sizeof(CONTEXT);
1140:
1141: return 0;
1142:
1.1.1.5 ! root 1143: case PFSTAT:
! 1144:
! 1145: {
! 1146:
! 1147: FILEPTR *pf;
! 1148:
! 1149: int pfd = (*(ushort *)buf);
! 1150:
! 1151: if (pfd < MIN_HANDLE || pfd >= MAX_OPEN ||
! 1152:
! 1153: !(pf = p->handle[pfd]))
! 1154:
! 1155: return EIHNDL;
! 1156:
! 1157: return (*pf->fc.fs->getxattr)(&pf->fc, (XATTR *)buf);
! 1158:
! 1159: }
! 1160:
1.1 root 1161: case PSETFLAGS:
1162:
1.1.1.3 root 1163: {
1164:
1165: int newflags = (ushort)(*(long *)buf);
1166:
1167: if ((newflags & F_OS_SPECIAL) &&
1168:
1169: (!(p->memflags & F_OS_SPECIAL))) {
1170:
1171: /* you're making the process OS_SPECIAL */
1172:
1173: TRACE(("Fcntl OS_SPECIAL pid %d",p->pid));
1174:
1175: p->memflags = newflags;
1176:
1177: mem_prot_special(p);
1178:
1179: }
1180:
1.1 root 1181: /* note: only the low 16 bits are actually used */
1182:
1183: p->memflags = *((long *)buf);
1184:
1185: return 0;
1186:
1.1.1.3 root 1187: }
1188:
1.1 root 1189: case PGETFLAGS:
1190:
1191: *((long *)buf) = p->memflags;
1192:
1193: return 0;
1194:
1.1.1.2 root 1195: case PTRACESFLAGS:
1196:
1197: if (p->ptracer == curproc || p->ptracer == 0) {
1198:
1199: p->ptraceflags = *(ushort *)buf;
1200:
1201: if (p->ptraceflags == 0) {
1202:
1203: p->ptracer = 0;
1204:
1205: p->ctxt[CURRENT].ptrace = 0;
1206:
1207: p->ctxt[SYSCALL].ptrace = 0;
1208:
1.1.1.4 root 1209: /* if the process is stopped, restart it */
1210:
1211: if (p->wait_q == STOP_Q) {
1212:
1213: p->sigpending &= ~STOPSIGS;
1.1.1.2 root 1214:
1.1.1.4 root 1215: post_sig(p, SIGCONT);
1216:
1217: }
1218:
1219: } else if (p == curproc) {
1.1.1.2 root 1220:
1221: p->ptracer = pid2proc(p->ppid);
1222:
1223: } else {
1224:
1225: p->ptracer = curproc;
1226:
1227: }
1228:
1229: } else {
1230:
1231: DEBUG(("proc_ioctl: process already being traced"));
1232:
1233: return EACCDN;
1234:
1235: }
1236:
1237: return 0;
1238:
1239: case PTRACEGFLAGS:
1240:
1241: if (p->ptracer == curproc) {
1242:
1243: *(ushort *)buf = p->ptraceflags;
1244:
1245: return 0;
1246:
1247: } else {
1248:
1249: return EACCDN;
1250:
1251: }
1252:
1253: case PTRACE11:
1254:
1255: return EINVFN;
1256:
1257: case PTRACEFLOW:
1258:
1259: if (mcpu < 20) {
1260:
1261: DEBUG(("proc_ioctl: wrong processor"));
1262:
1263: return EINVFN;
1264:
1265: }
1266:
1267: /* fall through */
1268:
1269: case PTRACEGO:
1270:
1271: case PTRACESTEP:
1272:
1273: if (!p->ptracer) {
1274:
1275: DEBUG(("proc_ioctl(PTRACE): process not being traced"));
1276:
1277: return EACCDN;
1278:
1279: }
1280:
1281: else if (p->wait_q != STOP_Q) {
1282:
1283: DEBUG(("proc_ioctl(PTRACE): process not stopped"));
1284:
1285: return EACCDN;
1286:
1287: }
1288:
1289: else if (p->wait_cond &&
1290:
1291: (1L << ((p->wait_cond >> 8) & 0x1f)) & STOPSIGS) {
1292:
1293: DEBUG(("proc_ioctl(PTRACE): process stopped by job control"));
1294:
1295: return EACCDN;
1296:
1297: }
1298:
1.1.1.4 root 1299: if (buf && *(ushort *)buf >= NSIG) {
1300:
1301: DEBUG(("proc_ioctl(PTRACE): illegal signal number"));
1302:
1303: return ERANGE;
1304:
1305: }
1306:
1.1.1.2 root 1307: p->ctxt[SYSCALL].sr &= 0x3fff; /* clear both trace bits */
1308:
1309: p->ctxt[SYSCALL].sr |= (mode - PTRACEGO) << 14;
1310:
1311: p->sigpending = 0;
1312:
1313: if (buf && *(ushort *)buf != 0) {
1314:
1315: TRACE(("PTRACEGO: sending signal %d to pid %d", *(ushort *)buf, p->pid));
1316:
1317: post_sig(p, *(ushort *)buf);
1318:
1319:
1320:
1321: /* another SIGNULL hack... within check_sigs() we watch for a pending
1322:
1323: * SIGNULL, if we see this then we allow delivery of a signal to the
1324:
1325: * process, rather than telling the parent.
1326:
1327: */
1328:
1329: p->sigpending |= 1L;
1330:
1331: } else {
1332:
1333: TRACE(("PTRACEGO: no signal"));
1334:
1335: }
1336:
1337: /* wake the process up */
1338:
1.1.1.5 ! root 1339: sr = spl7();
! 1340:
1.1.1.2 root 1341: rm_q(p->wait_q, p);
1342:
1343: add_q(READY_Q, p);
1344:
1.1.1.5 ! root 1345: spl(sr);
! 1346:
1.1.1.2 root 1347: return 0;
1348:
1.1.1.4 root 1349: /* jr: PLOADINFO returns information about params passed to Pexec */
1350:
1351: case PLOADINFO:
1352:
1353: {
1354:
1355: struct ploadinfo *pl = buf;
1356:
1357:
1358:
1359: if (!p->fname[0]) return EFILNF;
1360:
1361: strncpy (pl->cmdlin, p->cmdlin, 128);
1362:
1363: if (strlen (p->fname) <= pl->fnamelen)
1364:
1365: strcpy (pl->fname, p->fname);
1366:
1367: else
1368:
1369: return ENAMETOOLONG;
1370:
1371: }
1372:
1373: return 0;
1374:
1375:
1376:
1.1 root 1377: case FIONREAD:
1378:
1379: case FIONWRITE:
1380:
1381: *((long *)buf) = 1L; /* we're always ready for i/o */
1382:
1383: return 0;
1384:
1385: default:
1386:
1.1.1.2 root 1387: DEBUG(("procfs: bad Fcntl command"));
1.1 root 1388:
1389: }
1390:
1391: return EINVFN;
1392:
1393: }
1394:
1395:
1396:
1.1.1.2 root 1397: static long ARGS_ON_STACK
1.1 root 1398:
1399: proc_lseek(f, where, whence)
1400:
1401: FILEPTR *f; long where; int whence;
1402:
1403: {
1404:
1405: switch(whence) {
1406:
1407: case 0:
1408:
1.1.1.5 ! root 1409: case 2:
! 1410:
1.1 root 1411: f->pos = where;
1412:
1413: break;
1414:
1415: case 1:
1416:
1417: f->pos += where;
1418:
1419: break;
1420:
1421: default:
1422:
1423: return EINVFN;
1424:
1425: }
1426:
1427: return f->pos;
1428:
1429: }
1430:
1431:
1432:
1.1.1.2 root 1433: static long ARGS_ON_STACK
1.1 root 1434:
1435: proc_datime(f, timeptr, rwflag)
1436:
1437: FILEPTR *f;
1438:
1439: short *timeptr;
1440:
1441: int rwflag;
1442:
1443: {
1444:
1445: PROC *p;
1446:
1447:
1448:
1449: p = (PROC *)f->devinfo;
1450:
1451: if (rwflag) {
1452:
1453: return EACCDN;
1454:
1455: }
1456:
1457: else {
1458:
1459: *timeptr++ = p->starttime;
1460:
1.1.1.2 root 1461: *timeptr = p->startdate;
1.1 root 1462:
1463: }
1464:
1465: return 0;
1466:
1467: }
1468:
1469:
1470:
1.1.1.2 root 1471: static long ARGS_ON_STACK
1.1 root 1472:
1473: proc_close(f, pid)
1474:
1475: FILEPTR *f;
1476:
1477: int pid;
1478:
1479: {
1480:
1.1.1.2 root 1481: UNUSED(f); UNUSED(pid);
1482:
1.1 root 1483: return 0;
1484:
1485: }
1486:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.