sys_signal.c

Go to the documentation of this file.
00001 
00006 #include "routix/system.h"
00007 #include "routix/debug.h"
00008 #include "sys/syscalls.h"
00009 #include "routix/syscalls.h"
00010 #include "error.h"
00011 #include "string.h"
00012 #include "routix/task.h"
00013 #include "routix/signal.h"
00014 
00015 extern task_struct_t *actual;
00016 
00017 
00018 int (*syscall_signals[MAX_SYSCALLS]) (void) = {
00019         (int (*) (void)) sys_kill,
00020         (int (*) (void)) sys_signal,
00021         (int (*) (void)) sys_sigaction,
00022         (int (*) (void)) sys_signal_check,
00023         (int (*) (void)) sys_sigprocmask
00024 
00025 };
00026 int _sys_kill(task_struct_t *proceso, int signo);
00027  
00028  
00036 int sys_kill(pid_t pid, int signo)
00037 {       
00038         if (getvar("__sig")==1)
00039                 kprintf("Recibida la senal: %d para el proceso: %d\n", signo, pid);
00040         // La señal que se intenta enviar, no existe
00041         if (signo > SIGMAX) {
00042                 actual->err_no = EINVAL;
00043                 return -1;
00044         }
00045         
00046         task_struct_t *proceso;
00047         proceso = encontrar_proceso_por_pid(pid);
00048 
00049         return _sys_kill(proceso, signo);
00050 }       
00051 
00052 
00062 int _sys_kill(task_struct_t *proceso, int signo)
00063 {
00064         // Si el proceso no existe
00065         if (!proceso) {
00066                 actual->err_no = ESRCH;
00067                 return -1;
00068         }
00069 
00070         // Por ahora init solo puede recibir SIGCHLD
00071         if (proceso==init_task && signo!=SIGCHLD)       {
00072                 actual->err_no = ESRCH;
00073                 return -1;
00074         }
00075 
00076         // Si la señal no se la está ignorando, marcarla como pendiente
00077         if (TASK_SIGNAL_HANDLER(proceso, signo) != SIG_IGN) {
00078                 TASK_SIGPENDING(proceso) = TASK_SIGPENDING(proceso)  | (1 << signo);
00079                 // Aqui "encolo" las señales pendientes de un mismo tipo
00080                 TASK_SIGNAL_COUNT(proceso, signo)++;
00081         }
00082         return 0;
00083 }
00084 
00085 
00092 void *sys_signal (int signo, void (*func)()) 
00093 {
00094         void (*old_func)() = TASK_SIGNAL_HANDLER(actual, signo);
00095         // Verificar si la función "func" pertenece al espacio de direcciones del usuario
00096         TASK_SIGNAL_HANDLER(actual, signo) = func;
00097         if (getvar("__sig")==1)
00098                 kprintf("Direccion de la funcion especificada: 0x%x\n", func);
00099         return old_func;
00100 }
00101 
00104 void sys_signal_correct(void)
00105 {
00106         //kprintf("SYS_SIGNAL_CORRECT");
00107         
00108         struct int_regs_ext *contexto = GET_CONTEXT(actual);
00109         
00110         contexto->esp += 4;
00111         
00112         //__debug();
00113 }
00114 
00115 
00121 void sys_signal_check (void)
00122 {
00123         struct int_regs_ext *context = GET_CONTEXT(actual);
00124 
00125         // Porque es esto ??? Bla bla... no estoy seguro...
00126         context->esp += 4;
00127 
00128         // Obtener la dirección física del stack de la tarea
00129         unsigned long *user_ptr = (unsigned long *) convertir_direccion( context->esp, actual->cr3_backup); 
00130 
00131         // Obtengo el valor de sigmask valido antes de ejecutar este handler que acaba de finalizar
00132         TASK_SIGMASK(actual) = *(user_ptr++);
00133 
00134         // Si no hay otras selañes pendientes... reacomodo el stack y retorno
00135         if (check_sigpending(actual, 0)<1)      {
00136                 context->esp += 4;
00137 //              kprintf("SYS_SIGNAL_CHECK: No hay otras pendientes\n");
00138         }
00139         // Si hay otra señal pendiente, pongo el EIP del contexto para que apunte al nuevo handler
00140         else {
00141 //              kprintf("SYS_SIGNAL_CHECK: HAY !!! pendientes\n");
00142         }
00143 
00144 }
00145 
00154 int sys_sigprocmask(int flag, sigset_t *set, sigset_t *old_set)
00155 {
00156         old_set = (old_set == NULL) ? NULL : convertir_direccion(old_set, actual->cr3_backup);
00157         set = (set == NULL) ? NULL : (sigset_t *)convertir_direccion(set, actual->cr3_backup);
00158         
00159         // Si old_set no es NULL, retorno en el la máscaraa ctual
00160         if (old_set) {
00161                 *old_set = TASK_SIGMASK(actual);
00162                 if (!set)
00163                         return 0;
00164         }
00165 
00166                 
00167         switch (flag) {
00168                 case SIG_BLOCK:
00169                         TASK_SIGMASK(actual) |= *set;
00170                         break;
00171                 case SIG_UNBLOCK:
00172                         TASK_SIGMASK(actual) = TASK_SIGMASK(actual) & (~*set);
00173                         break;
00174                 case SIG_SETMASK:
00175                         TASK_SIGMASK(actual) = *set;
00176                         break;
00177                 default:
00178                         actual->err_no = EINVAL;
00179                         return -1;
00180 
00181         }
00182                         
00183         //kpanic("sigprocmask");
00184         return 0;
00185 }
00186 
00194 int sys_sigaction (int signo, struct sigaction *act, struct sigaction *oact) 
00195 {
00196         
00197         if (signo >= SIGMAX)    {
00198                 actual->err_no = EINVAL;
00199                 return -1;
00200         }
00201         
00202         oact = (oact == NULL) ? NULL : convertir_direccion(oact, actual->cr3_backup);
00203         act = (act == NULL) ? NULL : convertir_direccion(act, actual->cr3_backup);
00204 
00205         if (oact)
00206                 memcpy (oact, &(TASK_SIGNAL(actual, signo)), sizeof (struct sigaction));
00207         
00208         if (act)
00209                 memcpy (&(TASK_SIGNAL(actual, signo)), act, sizeof (struct sigaction));
00210         
00211         return 0;
00212 }
00213 

Generated on Sun May 30 18:38:35 2004 for Routix OS by doxygen 1.3.6