/* 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); }