/* 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 . */
#include "signal.h"
#include "sched.h"
#include "idle.h"
#include "proc_struct.h"
#include
#include
#include
#include
#include
#include
#include
#include
/* 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(¤t->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(¤t->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(¤t->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(¤t->vm, (unsigned long)addr, len, prot, file_descr, off)) < 0)
return (void *)rv;
}
else
if ((rv = vm_map_anon(¤t->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(¤t->vm, (unsigned long)addr, len);
}
int memory_protect(void *addr, unsigned int len, int prot)
{
return vm_protect(¤t->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(¤t->vm, cause, access, stack_top, laddr);
}