View of xos/kernel/current.c


XOS | Parent Directory | View | Download

/* Copyright (C) 2008  Emmanuel Varoquaux
 
   This file is part of XOS.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
 
   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
 
#include "signal.h"
#include "sched.h"
#include "idle.h"
#include "proc_struct.h"
 
#include <fd.h>
#include <vm.h>
#include <system.h>
#include <system_data_structs.h>
#include <asm.h>
#include <errno.h>
#include <string.h>
#include <stddef.h>
 
/* Identite */
 
int is_idle()
{
  return current == idle;
}
 
int get_pid()
{
  return current->id;
}
 
int get_pgid()
{
  return current->group->id;
}
 
struct file_struct *get_wd()
{
  return current->wd;
}
 
/* Descripteurs de fichiers */
 
static int get_free_fd(int start, int *fd)
{
  for (*fd = start; *fd < OPEN_MAX; (*fd)++)
    if (!current->file_descr_table[*fd])
      return 1;
  return 0;
}
 
/* Retourne un code d'erreur en cas d'echec d'allocation. */
int alloc_fd(int start, struct file_descr_struct *file_descr, int *fd)
{
  if (!get_free_fd(start, fd))
    return -EMFILE;
  current->file_descr_table[*fd] = file_descr;
  return 0;
}
 
/* fd doit etre valide. Utiliser get_file_descr() pour tester sa validite. */
void free_fd(int fd)
{
  current->file_descr_table[fd] = NULL;
}
 
/* Retourne le fichier associe au descripteur fd, ou NULL si aucun fichier ne
 * lui est associe. */
struct file_descr_struct *get_file_descr(int fd)
{
  if (fd < 0 || fd >= OPEN_MAX)
    return NULL;
  return current->file_descr_table[fd];
}
 
/* Processus fils */
 
/* Dit si proc est un fils du processus courant. */
int is_child(const struct proc_struct *proc)
{
  return proc->parent == current;
}
 
/* Signaux */
 
void signal_self(int sig)
{
  signal(current, sig);
}
 
/* Ordonnancement */
 
/* Cede le CPU a un autre processus. */
void yield()
{
  int intr;
 
  disable_intr(intr);
  schedule();
  restore_intr(intr);
}
 
/* Memoire */
 
static inline int is_user_fs()
{
  unsigned short fs;
  struct sel_data_struct sel_data;
 
  get_fs(fs);
  get_sel(&fs, &sel_data);
  return sel_data.rpl;
}
 
/* Verifie la validite d'un acces a la zone memoire commencant a l'adresse
 * virtuelle fs:ptr et de longueur size. Remplit les tables des pages le cas
 * echeant.
 * Retourne une valeur non nulle en cas de succes, 0 en cas d'echec. */
int verify_area(const void *fs_ptr, unsigned int size, int access)
{
  return is_user_fs() ? vm_verify_area(&current->vm, (unsigned long)fs_ptr, size, access) : 1;
}
 
/* Verifie la validite d'un acces en lecture a la chaine de caracteres
 * commencant a l'adresse virtuelle fs:ptr et se terminant par un caractere
 * nul. Remplit les tables des pages le cas echeant.
 * Le parametre n indique une longueur maximale de la zone memoire a examiner.
 * Si len est non nul, il est positionne a la longueur de la chaine de
 * caracteres, dans la limite de n caracteres.
 * Retourne une valeur non nulle en cas de succes, 0 en cas d'echec. */
int verify_str(const char *fs_str, unsigned int n, unsigned int *len)
{
  if (!is_user_fs()) {
    if (len)
      *len = strnlen(fs_str, n);
    return 1;
  }
  else
    return vm_verify_str(&current->vm, (unsigned long)fs_str, n, len);
}
 
void *memory_map(void *addr, unsigned int len, int prot, int fd, long off)
{
  struct file_descr_struct *file_descr;
  int rv;
 
  if (!addr)
    if (!(addr = (void *)vm_get_free_area(&current->vm, 0, MAPS_TOP, len, 0)))
      return (void *)-ENOMEM;
  if (fd != -1) {
    if (!(file_descr = current->file_descr_table[fd]))
      return (void *)-EBADF;
    if ((rv = fd_map(&current->vm, (unsigned long)addr, len, prot, file_descr, off)) < 0)
      return (void *)rv;
  }
  else
    if ((rv = vm_map_anon(&current->vm, (unsigned long)addr, len, prot, 0, NULL)) < 0)
      return (void *)rv;
  return addr;
}
 
int memory_unmap(void *addr, unsigned int len)
{
  return vm_unmap(&current->vm, (unsigned long)addr, len);
}
 
int memory_protect(void *addr, unsigned int len, int prot)
{
  return vm_protect(&current->vm, (unsigned long)addr, len, prot);
}
 
/* Appelle le gestionnaire de defaut de page. */
int handle_page_fault(int cause, int access, unsigned long stack_top, unsigned long laddr)
{
  return vm_handle_page_fault(&current->vm, cause, access, stack_top, laddr);
}