[BACK]Return to main.c CVS log [TXT][DIR] Up to [local] / prex-old / usr / server / proc

Diff for /prex-old/usr/server/proc/main.c between version 1.1.1.1 and 1.1.1.1.2.1

version 1.1.1.1, 2008/06/03 10:38:51 version 1.1.1.1.2.1, 2008/08/13 17:12:45
Line 1 
Line 1 
 /*  /*
  * Copyright (c) 2005-2007, Kohsuke Ohtani   * Copyright (c) 2005-2008, Kohsuke Ohtani
  * All rights reserved.   * All rights reserved.
  *   *
  * Redistribution and use in source and binary forms, with or without   * Redistribution and use in source and binary forms, with or without
Line 30 
Line 30 
 /*  /*
  * Process server:   * Process server:
  *   *
  * A process server is responsible to handle process ID, group ID,   * A process server is responsible to handle process ID, group
  * signal and fork()/exec() state. Since Prex microkernel does not   * ID, signal and fork()/exec() state. Since Prex microkernel
  * have the concept about process or process group, the process   * does not have the concept about process or process group, the
  * server will map each Prex task to POSIX process.   * process server will map each Prex task to POSIX process.
  *   *
  * Prex does not support uid (user ID) and gid (group ID) because   * Prex does not support uid (user ID) and gid (group ID) because
  * it runs only in a single user mode. The value of uid and gid is   * it runs only in a single user mode. The value of uid and gid is
Line 41 
Line 41 
  * library stubs, and it is out of scope in this server.   * library stubs, and it is out of scope in this server.
  *   *
  * Important Notice:   * Important Notice:
  * This server is made as a single thread program to reduce many locks   * This server is made as a single thread program to reduce many
  * and to keep the code clean. So, we should not block in the kernel   * locks and to keep the code clean. So, we should not block in
  * for any service. If some service must wait an event, it should wait   * the kernel for any service. If some service must wait an
  * within the library stub in the client application.   * event, it should wait within the library stub in the client
    * application.
  */   */
   
 #include <prex/prex.h>  #include <prex/prex.h>
Line 60 
Line 61 
 #include "proc.h"  #include "proc.h"
   
 /* forward declarations */  /* forward declarations */
 static int proc_version(struct msg *msg);  static int proc_debug(struct msg *);
 static int proc_debug(struct msg *msg);  static int proc_shutdown(struct msg *);
 static int proc_shutdown(struct msg *msg);  static int proc_exec(struct msg *);
 static int proc_exec(struct msg *msg);  static int proc_pstat(struct msg *);
 static int proc_pstat(struct msg *msg);  static int proc_register(struct msg *);
 static int proc_register(struct msg *msg);  static int proc_setinit(struct msg *);
 static int proc_setinit(struct msg *msg);  
   
 /*  /*
  * Message mapping   * Message mapping
Line 77 
Line 77 
 };  };
   
 static const struct msg_map procmsg_map[] = {  static const struct msg_map procmsg_map[] = {
         {STD_VERSION,   proc_version},  
         {STD_DEBUG,     proc_debug},          {STD_DEBUG,     proc_debug},
         {STD_SHUTDOWN,  proc_shutdown},          {STD_SHUTDOWN,  proc_shutdown},
         {PS_GETPID,     proc_getpid},          {PS_GETPID,     proc_getpid},
         {PS_GETPPID,    proc_getppid},          {PS_GETPPID,    proc_getppid},
         {PS_GETPGID,    proc_getpgid},          {PS_GETPGID,    proc_getpgid},
         {PS_SETPGID,    proc_setpgid},          {PS_SETPGID,    proc_setpgid},
           {PS_GETSID,     proc_getsid},
           {PS_SETSID,     proc_setsid},
         {PS_FORK,       proc_fork},          {PS_FORK,       proc_fork},
         {PS_EXIT,       proc_exit},          {PS_EXIT,       proc_exit},
         {PS_STOP,       proc_stop},          {PS_STOP,       proc_stop},
Line 93 
Line 94 
         {PS_PSTAT,      proc_pstat},          {PS_PSTAT,      proc_pstat},
         {PS_REGISTER,   proc_register},          {PS_REGISTER,   proc_register},
         {PS_SETINIT,    proc_setinit},          {PS_SETINIT,    proc_setinit},
         {0,             0},          {0,             NULL},
 };  };
   
 static struct proc proc0;       /* process data of this server (pid=0) */  static struct proc proc0;       /* process data of this server (pid=0) */
 static struct pgrp pgrp0;       /* process group for process server */  static struct pgrp pgrp0;       /* process group for first process */
   static struct session session0; /* session for first process */
   
 struct proc initproc;           /* process slot for init process (pid=1) */  struct proc initproc;           /* process slot for init process (pid=1) */
 struct proc *curproc;           /* current (caller) process */  struct proc *curproc;           /* current (caller) process */
 struct list allproc;            /* list of all processes */  struct list allproc;            /* list of all processes */
   
   /*
    * Create a new process.
    */
 static void  static void
 newproc(struct proc *p, pid_t pid, task_t task)  newproc(struct proc *p, pid_t pid, task_t task)
 {  {
   
         p->parent = &proc0;          p->p_parent = &proc0;
         p->pgrp = &pgrp0;          p->p_pgrp = &pgrp0;
         p->stat = SRUN;          p->p_stat = SRUN;
         p->exit_code = 0;          p->p_exitcode = 0;
         p->wait_vfork = 0;          p->p_vforked = 0;
         p->pid = pid;          p->p_pid = pid;
         p->task = task;          p->p_task = task;
         list_init(&p->children);          list_init(&p->p_children);
         list_insert(&allproc, &p->link);          list_insert(&allproc, &p->p_link);
         proc_add(p);          proc_add(p);
         list_insert(&proc0.children, &p->sibling);          list_insert(&proc0.p_children, &p->p_sibling);
         list_insert(&pgrp0.members, &p->pgrp_link);          list_insert(&pgrp0.pg_members, &p->p_pgrp_link);
 }  }
   
 /*  /*
  * exec() - Update pid to track the mapping with task id.   * exec() - Update pid to track the mapping with task id.
  *   * The almost all work is done by a exec server for exec()
  * The almost all work is done by a exec server for exec() emulation.   * emulation. So, there is not so many jobs here...
  * So, there is not so many jobs here...  
  */   */
 static int  static int
 proc_exec(struct msg *msg)  proc_exec(struct msg *msg)
 {  {
         task_t org_task, new_task;          task_t orgtask, newtask;
         struct proc *p, *parent;          struct proc *p, *parent;
   
         dprintf("proc_exec: proc=%x\n", curproc);          DPRINTF(("proc_exec: pid=%x\n", curproc->p_pid));
         org_task = msg->data[0];  
         new_task = msg->data[1];          orgtask = (task_t)msg->data[0];
         if ((p = task_to_proc(org_task)) == NULL)          newtask = (task_t)msg->data[1];
           if ((p = task_to_proc(orgtask)) == NULL)
                 return EINVAL;                  return EINVAL;
   
         proc_remove(p);          proc_remove(p);
         p->task = new_task;          p->p_task = newtask;
         proc_add(p);          proc_add(p);
         p->stack_base = (void *)msg->data[2];          p->p_stackbase = (void *)msg->data[2];
   
         parent = p->parent;          parent = p->p_parent;
         if (parent != NULL && parent->wait_vfork)          if (parent != NULL && parent->p_vforked)
                 vfork_end(parent);                  vfork_end(parent);
         return 0;          return 0;
 }  }
Line 159 
Line 164 
         task_t task;          task_t task;
         struct proc *p;          struct proc *p;
   
         dprintf("proc_pstat: task=%x\n", msg->data[0]);          DPRINTF(("proc_pstat: task=%x\n", msg->data[0]));
         task = msg->data[0];  
           task = (task_t)msg->data[0];
         if ((p = task_to_proc(task)) == NULL)          if ((p = task_to_proc(task)) == NULL)
                 return EINVAL;                  return EINVAL;
   
         msg->data[0] = (int)p->pid;          msg->data[0] = (int)p->p_pid;
         msg->data[2] = (int)p->stat;          msg->data[2] = (int)p->p_stat;
         if (p->parent == NULL)          if (p->p_parent == NULL)
                 msg->data[1] = (int)0;                  msg->data[1] = (int)0;
         else          else
                 msg->data[1] = (int)p->parent->pid;                  msg->data[1] = (int)p->p_parent->p_pid;
         return 0;          return 0;
 }  }
   
Line 182 
Line 188 
         struct proc *p;          struct proc *p;
   
         p = &initproc;          p = &initproc;
         if (p->stat == SRUN)          if (p->p_stat == SRUN)
                 return EPERM;                  return EPERM;
   
         newproc(p, 1, msg->hdr.task);          newproc(p, 1, msg->hdr.task);
Line 201 
Line 207 
         if ((p = malloc(sizeof(struct proc))) == NULL)          if ((p = malloc(sizeof(struct proc))) == NULL)
                 return ENOMEM;                  return ENOMEM;
   
         if ((pid = pid_assign()) == 0)          if ((pid = pid_assign()) == 0) {
                   free(p);
                 return EAGAIN;  /* Too many processes */                  return EAGAIN;  /* Too many processes */
           }
         newproc(p, pid, msg->hdr.task);          newproc(p, pid, msg->hdr.task);
         return 0;          return 0;
 }  }
   
 static int  static int
 proc_version(struct msg *msg)  
 {  
   
         return 0;  
 }  
   
 static int  
 proc_shutdown(struct msg *msg)  proc_shutdown(struct msg *msg)
 {  {
   
Line 228 
Line 228 
 #ifdef DEBUG_PROC  #ifdef DEBUG_PROC
         struct proc *p;          struct proc *p;
         list_t n;          list_t n;
         char stat[][5] = { "RUN ", "ZOMB", "STOP" };          char stat[][5] = { "    ", "RUN ", "ZOMB", "STOP" };
   
         printf("<Process Server>\n");          dprintf("<Process Server>\n");
         printf("Dump process\n");          dprintf("Dump process\n");
         printf(" pid    ppid   stat task\n");          dprintf(" pid    ppid   pgid   sid    stat task\n");
         printf(" ------ ------ ---- --------\n");          dprintf(" ------ ------ ------ ------ ---- --------\n");
   
         for (n = list_first(&allproc); n != &allproc;          for (n = list_first(&allproc); n != &allproc;
              n = list_next(n)) {               n = list_next(n)) {
                 p = list_entry(n, struct proc, link);                  p = list_entry(n, struct proc, p_link);
                 printf(" %6d %6d %s %08x\n",                  dprintf(" %6d %6d %6d %6d %s %08x\n", p->p_pid,
                        p->pid, p->parent->pid, stat[p->stat], p->task);                          p->p_parent->p_pid, p->p_pgrp->pg_pgid,
                           p->p_pgrp->pg_session->s_leader->p_pid,
                           stat[p->p_stat], p->p_task);
         }          }
         printf("\n");          dprintf("\n");
 #endif  #endif
         return 0;          return 0;
 }  }
Line 250 
Line 253 
 {  {
         struct proc *p;          struct proc *p;
   
           p = &proc0;
           curproc = p;
   
         tty_init();          tty_init();
         table_init();          table_init();
           list_init(&allproc);
   
         /*          /*
          * Setup a process for ourselves.           * Create process 0 (the process server)
          * pid=0 is always reserved by process server.  
          */           */
         p = &proc0;          pgrp0.pg_pgid = 0;
         p->parent = 0;          list_init(&pgrp0.pg_members);
         p->pgrp = &pgrp0;  
         p->stat = SRUN;  
         p->exit_code = 0;  
         p->wait_vfork = 0;  
         p->pid = 0;  
         p->task = task_self();  
         list_init(&p->children);  
         list_init(&allproc);  
         list_init(&pgrp0.members);  
         proc_add(p);  
         pgrp_add(&pgrp0);          pgrp_add(&pgrp0);
         list_insert(&pgrp0.members, &p->pgrp_link);  
           pgrp0.pg_session = &session0;
           session0.s_refcnt = 1;
           session0.s_leader = p;
           session0.s_ttyhold = 0;
   
           p->p_pgrp = &pgrp0;
           p->p_parent = 0;
           p->p_stat = SRUN;
           p->p_exitcode = 0;
           p->p_vforked = 0;
           p->p_pid = 0;
           p->p_task = task_self();
           list_init(&p->p_children);
           proc_add(p);
           list_insert(&pgrp0.pg_members, &p->p_pgrp_link);
   
           DPRINTF(("proc0=%x init=%x\n", &proc0, &initproc));
 }  }
   
 /*  /*
Line 322 
Line 335 
                                 curproc = task_to_proc(msg.hdr.task);                                  curproc = task_to_proc(msg.hdr.task);
   
                                 /* Update the capability of caller task. */                                  /* Update the capability of caller task. */
                                 if (curproc && task_getcap(msg.hdr.task,                                  if (curproc &&
                                                            &curproc->cap))                                      task_getcap(msg.hdr.task, &curproc->p_cap))
                                         break;                                          break;
   
                                 err = map->func(&msg);                                  err = (*map->func)(&msg);
                                 break;                                  break;
                         }                          }
                         map++;                          map++;
Line 338 
Line 351 
                 msg_reply(obj, &msg, sizeof(msg));                  msg_reply(obj, &msg, sizeof(msg));
 #ifdef DEBUG_PROC  #ifdef DEBUG_PROC
                 if (err)                  if (err)
                         dprintf("msg code=%x error=%d\n", map->code, err);                          DPRINTF(("proc: msg code=%x error=%d\n", map->code,
                                    err));
 #endif  #endif
         }          }
         return 0;          return 0;

Legend:
Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.1.2.1

CVSweb