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