home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / KERNEL-S / V1.0 / LINUX-1.0 / LINUX-1 / linux / fs / proc / mem.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-01  |  3.4 KB  |  171 lines

  1. /*
  2.  *  linux/fs/proc/mem.c
  3.  *
  4.  *  Copyright (C) 1991, 1992  Linus Torvalds
  5.  */
  6.  
  7. #include <linux/types.h>
  8. #include <linux/errno.h>
  9. #include <linux/sched.h>
  10. #include <linux/kernel.h>
  11.  
  12. #include <asm/segment.h>
  13. #include <asm/io.h>
  14.  
  15. /*
  16.  * mem_write isn't really a good idea right now. It needs
  17.  * to check a lot more: if the process we try to write to 
  18.  * dies in the middle right now, mem_write will overwrite
  19.  * kernel memory.. This disables it altogether.
  20.  */
  21. #define mem_write NULL
  22.  
  23. static int mem_read(struct inode * inode, struct file * file,char * buf, int count)
  24. {
  25.     unsigned long addr, pid, cr3;
  26.     char *tmp;
  27.     unsigned long pte, page;
  28.     int i;
  29.  
  30.     if (count < 0)
  31.         return -EINVAL;
  32.     pid = inode->i_ino;
  33.     pid >>= 16;
  34.     cr3 = 0;
  35.     for (i = 1 ; i < NR_TASKS ; i++)
  36.         if (task[i] && task[i]->pid == pid) {
  37.             cr3 = task[i]->tss.cr3;
  38.             break;
  39.         }
  40.     if (!cr3)
  41.         return -EACCES;
  42.     addr = file->f_pos;
  43.     tmp = buf;
  44.     while (count > 0) {
  45.         if (current->signal & ~current->blocked)
  46.             break;
  47.         pte = *PAGE_DIR_OFFSET(cr3,addr);
  48.         if (!(pte & PAGE_PRESENT))
  49.             break;
  50.         pte &= PAGE_MASK;
  51.         pte += PAGE_PTR(addr);
  52.         page = *(unsigned long *) pte;
  53.         if (!(page & 1))
  54.             break;
  55.         page &= PAGE_MASK;
  56.         page += addr & ~PAGE_MASK;
  57.         i = PAGE_SIZE-(addr & ~PAGE_MASK);
  58.         if (i > count)
  59.             i = count;
  60.         memcpy_tofs(tmp,(void *) page,i);
  61.         addr += i;
  62.         tmp += i;
  63.         count -= i;
  64.     }
  65.     file->f_pos = addr;
  66.     return tmp-buf;
  67. }
  68.  
  69. #ifndef mem_write
  70.  
  71. static int mem_write(struct inode * inode, struct file * file,char * buf, int count)
  72. {
  73.     unsigned long addr, pid, cr3;
  74.     char *tmp;
  75.     unsigned long pte, page;
  76.     int i;
  77.  
  78.     if (count < 0)
  79.         return -EINVAL;
  80.     addr = file->f_pos;
  81.     pid = inode->i_ino;
  82.     pid >>= 16;
  83.     cr3 = 0;
  84.     for (i = 1 ; i < NR_TASKS ; i++)
  85.         if (task[i] && task[i]->pid == pid) {
  86.             cr3 = task[i]->tss.cr3;
  87.             break;
  88.         }
  89.     if (!cr3)
  90.         return -EACCES;
  91.     tmp = buf;
  92.     while (count > 0) {
  93.         if (current->signal & ~current->blocked)
  94.             break;
  95.         pte = *PAGE_DIR_OFFSET(cr3,addr);
  96.         if (!(pte & PAGE_PRESENT))
  97.             break;
  98.         pte &= PAGE_MASK;
  99.         pte += PAGE_PTR(addr);
  100.         page = *(unsigned long *) pte;
  101.         if (!(page & PAGE_PRESENT))
  102.             break;
  103.         if (!(page & 2)) {
  104.             do_wp_page(0,addr,current,0);
  105.             continue;
  106.         }
  107.         page &= PAGE_MASK;
  108.         page += addr & ~PAGE_MASK;
  109.         i = PAGE_SIZE-(addr & ~PAGE_MASK);
  110.         if (i > count)
  111.             i = count;
  112.         memcpy_fromfs((void *) page,tmp,i);
  113.         addr += i;
  114.         tmp += i;
  115.         count -= i;
  116.     }
  117.     file->f_pos = addr;
  118.     if (tmp != buf)
  119.         return tmp-buf;
  120.     if (current->signal & ~current->blocked)
  121.         return -ERESTARTSYS;
  122.     return 0;
  123. }
  124.  
  125. #endif
  126.  
  127. static int mem_lseek(struct inode * inode, struct file * file, off_t offset, int orig)
  128. {
  129.     switch (orig) {
  130.         case 0:
  131.             file->f_pos = offset;
  132.             return file->f_pos;
  133.         case 1:
  134.             file->f_pos += offset;
  135.             return file->f_pos;
  136.         default:
  137.             return -EINVAL;
  138.     }
  139. }
  140.  
  141. static struct file_operations proc_mem_operations = {
  142.     mem_lseek,
  143.     mem_read,
  144.     mem_write,
  145.     NULL,        /* mem_readdir */
  146.     NULL,        /* mem_select */
  147.     NULL,        /* mem_ioctl */
  148.     NULL,        /* mmap */
  149.     NULL,        /* no special open code */
  150.     NULL,        /* no special release code */
  151.     NULL        /* can't fsync */
  152. };
  153.  
  154. struct inode_operations proc_mem_inode_operations = {
  155.     &proc_mem_operations,    /* default base directory file-ops */
  156.     NULL,            /* create */
  157.     NULL,            /* lookup */
  158.     NULL,            /* link */
  159.     NULL,            /* unlink */
  160.     NULL,            /* symlink */
  161.     NULL,            /* mkdir */
  162.     NULL,            /* rmdir */
  163.     NULL,            /* mknod */
  164.     NULL,            /* rename */
  165.     NULL,            /* readlink */
  166.     NULL,            /* follow_link */
  167.     NULL,            /* bmap */
  168.     NULL,            /* truncate */
  169.     NULL            /* permission */
  170. };
  171.