utility.c

Go to the documentation of this file.
00001 
00018 #include "pm.h"
00019 #include <sys/stat.h>
00020 #include <minix/callnr.h>
00021 #include <minix/com.h>
00022 #include <minix/endpoint.h>
00023 #include <fcntl.h>
00024 #include <signal.h>             /* needed only because mproc.h needs it */
00025 #include "mproc.h"
00026 #include "param.h"
00027 
00028 #include <minix/config.h>
00029 #include <timers.h>
00030 #include <string.h>
00031 #include "../../kernel/const.h"
00032 #include "../../kernel/config.h"
00033 #include "../../kernel/type.h"
00034 #include "../../kernel/proc.h"
00035 
00036 /*===========================================================================*
00037  *                              get_free_pid                                 *
00038  *===========================================================================*/
00039 PUBLIC pid_t get_free_pid()
00040 {
00041   static pid_t next_pid = INIT_PID + 1;         /* next pid to be assigned */
00042   register struct mproc *rmp;                   /* check process table */
00043   int t;                                        /* zero if pid still free */
00044 
00045   /* Find a free pid for the child and put it in the table. */
00046   do {
00047         t = 0;                  
00048         next_pid = (next_pid < NR_PIDS ? next_pid + 1 : INIT_PID + 1);
00049         for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++)
00050                 if (rmp->mp_pid == next_pid || rmp->mp_procgrp == next_pid) {
00051                         t = 1;
00052                         break;
00053                 }
00054   } while (t);                                  /* 't' = 0 means pid free */
00055   return(next_pid);
00056 }
00057 
00058 /*===========================================================================*
00059  *                              allowed                                      *
00060  *===========================================================================*/
00061 PUBLIC int allowed(name_buf, s_buf, mask)
00062 char *name_buf;                 /* pointer to file name to be EXECed */
00063 struct stat *s_buf;             /* buffer for doing and returning stat struct*/
00064 int mask;                       /* R_BIT, W_BIT, or X_BIT */
00065 {
00066 /* Check to see if file can be accessed.  Return EACCES or ENOENT if the access
00067  * is prohibited.  If it is legal open the file and return a file descriptor.
00068  */
00069   int fd;
00070   int save_errno;
00071 
00072   /* Use the fact that mask for access() is the same as the permissions mask.
00073    * E.g., X_BIT in <minix/const.h> is the same as X_OK in <unistd.h> and
00074    * S_IXOTH in <sys/stat.h>.  tell_fs(DO_CHDIR, ...) has set PM's real ids
00075    * to the user's effective ids, so access() works right for setuid programs.
00076    */
00077   if (access(name_buf, mask) < 0) return(-errno);
00078 
00079   /* The file is accessible but might not be readable.  Make it readable. */
00080   tell_fs(SETUID, PM_PROC_NR, (int) SUPER_USER, (int) SUPER_USER);
00081 
00082   /* Open the file and fstat it.  Restore the ids early to handle errors. */
00083   fd = open(name_buf, O_RDONLY | O_NONBLOCK);
00084   save_errno = errno;           /* open might fail, e.g. from ENFILE */
00085   tell_fs(SETUID, PM_PROC_NR, (int) mp->mp_effuid, (int) mp->mp_effuid);
00086   if (fd < 0) return(-save_errno);
00087   if (fstat(fd, s_buf) < 0) panic(__FILE__,"allowed: fstat failed", NO_NUM);
00088 
00089   /* Only regular files can be executed. */
00090   if (mask == X_BIT && (s_buf->st_mode & I_TYPE) != I_REGULAR) {
00091         close(fd);
00092         return(EACCES);
00093   }
00094   return(fd);
00095 }
00096 
00097 /*===========================================================================*
00098  *                              no_sys                                       *
00099  *===========================================================================*/
00100 PUBLIC int no_sys()
00101 {
00102 /* A system call number not implemented by PM has been requested. */
00103 
00104   return(ENOSYS);
00105 }
00106 
00107 /*===========================================================================*
00108  *                              panic                                        *
00109  *===========================================================================*/
00110 PUBLIC void panic(who, mess, num)
00111 char *who;                      /* who caused the panic */
00112 char *mess;                     /* panic message string */
00113 int num;                        /* number to go with it */
00114 {
00115 /* An unrecoverable error has occurred.  Panics are caused when an internal
00116  * inconsistency is detected, e.g., a programming error or illegal value of a
00117  * defined constant. The process manager decides to exit.
00118  */
00119   message m;
00120   int s;
00121 
00122   /* Switch to primary console and print panic message. */
00123   check_sig(mproc[TTY_PROC_NR].mp_pid, SIGTERM);
00124   printf("PM panic (%s): %s", who, mess);
00125   if (num != NO_NUM) printf(": %d",num);
00126   printf("\n");
00127    
00128   /* Exit PM. */
00129   sys_exit(SELF);
00130 }
00131 
00132 /*===========================================================================*
00133  *                              tell_fs                                      *
00134  *===========================================================================*/
00135 PUBLIC void tell_fs(what, p1, p2, p3)
00136 int what, p1, p2, p3;
00137 {
00138 /* This routine is only used by PM to inform FS of certain events:
00139  *      tell_fs(CHDIR, slot, dir, 0)
00140  *      tell_fs(EXEC, proc, 0, 0)
00141  *      tell_fs(EXIT, proc, 0, 0)
00142  *      tell_fs(FORK, parent, child, pid)
00143  *      tell_fs(SETGID, proc, realgid, effgid)
00144  *      tell_fs(SETSID, proc, 0, 0)
00145  *      tell_fs(SETUID, proc, realuid, effuid)
00146  *      tell_fs(UNPAUSE, proc, signr, 0)
00147  *      tell_fs(STIME, time, 0, 0)
00148  * Ignore this call if the FS is already dead, e.g. on shutdown.
00149  */
00150   message m;
00151 
00152   if ((mproc[FS_PROC_NR].mp_flags & (IN_USE|ZOMBIE)) != IN_USE)
00153       return;
00154 
00155   m.tell_fs_arg1 = p1;
00156   m.tell_fs_arg2 = p2;
00157   m.tell_fs_arg3 = p3;
00158   _taskcall(FS_PROC_NR, what, &m);
00159 }
00160 
00161 /*===========================================================================*
00162  *                              find_param                                   *
00163  *===========================================================================*/
00164 PUBLIC char *find_param(name)
00165 const char *name;
00166 {
00167   register const char *namep;
00168   register char *envp;
00169 
00170   for (envp = (char *) monitor_params; *envp != 0;) {
00171         for (namep = name; *namep != 0 && *namep == *envp; namep++, envp++)
00172                 ;
00173         if (*namep == '\0' && *envp == '=') 
00174                 return(envp + 1);
00175         while (*envp++ != 0)
00176                 ;
00177   }
00178   return(NULL);
00179 }
00180 
00181 /*===========================================================================*
00182  *                              get_mem_map                                  *
00183  *===========================================================================*/
00184 PUBLIC int get_mem_map(proc_nr, mem_map)
00185 int proc_nr;                                    /* process to get map of */
00186 struct mem_map *mem_map;                        /* put memory map here */
00187 {
00188   struct proc p;
00189   int s;
00190 
00191   if ((s=sys_getproc(&p, proc_nr)) != OK)
00192         return(s);
00193   memcpy(mem_map, p.p_memmap, sizeof(p.p_memmap));
00194   return(OK);
00195 }
00196 
00197 /*===========================================================================*
00198  *                              get_stack_ptr                                *
00199  *===========================================================================*/
00200 PUBLIC int get_stack_ptr(proc_nr_e, sp)
00201 int proc_nr_e;                                  /* process to get sp of */
00202 vir_bytes *sp;                                  /* put stack pointer here */
00203 {
00204   struct proc p;
00205   int s;
00206 
00207   if ((s=sys_getproc(&p, proc_nr_e)) != OK)
00208         return(s);
00209   *sp = p.p_reg.sp;
00210   return(OK);
00211 }
00212 
00213 /*===========================================================================*
00214  *                              proc_from_pid                                *
00215  *===========================================================================*/
00216 PUBLIC int proc_from_pid(mp_pid)
00217 pid_t mp_pid;
00218 {
00219         int rmp;
00220 
00221         for (rmp = 0; rmp < NR_PROCS; rmp++)
00222                 if (mproc[rmp].mp_pid == mp_pid)
00223                         return rmp;
00224 
00225         return -1;
00226 }
00227 
00228 /*===========================================================================*
00229  *                              pm_isokendpt                                 *
00230  *===========================================================================*/
00231 PUBLIC int pm_isokendpt(int endpoint, int *proc)
00232 {
00233         *proc = _ENDPOINT_P(endpoint);
00234         if(*proc < -NR_TASKS || *proc >= NR_PROCS)
00235                 return EINVAL;
00236         if(*proc >= 0 && endpoint != mproc[*proc].mp_endpoint)
00237                 return EDEADSRCDST;
00238         if(*proc >= 0 && !(mproc[*proc].mp_flags & IN_USE))
00239                 return EDEADSRCDST;
00240         return OK;
00241 }
00242 

Generated on Fri Apr 14 22:56:39 2006 for minix by  doxygen 1.4.6