utility.c

Go to the documentation of this file.
00001 /* This file contains a few general purpose utility routines.
00002  *
00003  * The entry points into this file are
00004  *   clock_time:  ask the clock task for the real time
00005  *   copy:        copy a block of data
00006  *   fetch_name:  go get a path name from user space
00007  *   no_sys:      reject a system call that FS does not handle
00008  *   panic:       something awful has occurred;  MINIX cannot continue
00009  *   conv2:       do byte swapping on a 16-bit int
00010  *   conv4:       do byte swapping on a 32-bit long
00011  */
00012 
00013 #include "fs.h"
00014 #include <minix/com.h>
00015 #include <minix/endpoint.h>
00016 #include <unistd.h>
00017 #include "buf.h"
00018 #include "file.h"
00019 #include "fproc.h"
00020 #include "inode.h"
00021 #include "param.h"
00022 
00023 PRIVATE int panicking;          /* inhibits recursive panics during sync */
00024 
00025 /*===========================================================================*
00026  *                              clock_time                                   *
00027  *===========================================================================*/
00028 PUBLIC time_t clock_time()
00029 {
00030 /* This routine returns the time in seconds since 1.1.1970.  MINIX is an
00031  * astrophysically naive system that assumes the earth rotates at a constant
00032  * rate and that such things as leap seconds do not exist.
00033  */
00034 
00035   register int k;
00036   clock_t uptime;
00037 
00038   if ( (k=getuptime(&uptime)) != OK) panic(__FILE__,"clock_time err", k);
00039   return( (time_t) (boottime + (uptime/HZ)));
00040 }
00041 
00042 /*===========================================================================*
00043  *                              fetch_name                                   *
00044  *===========================================================================*/
00045 PUBLIC int fetch_name(path, len, flag)
00046 char *path;                     /* pointer to the path in user space */
00047 int len;                        /* path length, including 0 byte */
00048 int flag;                       /* M3 means path may be in message */
00049 {
00050 /* Go get path and put it in 'user_path'.
00051  * If 'flag' = M3 and 'len' <= M3_STRING, the path is present in 'message'.
00052  * If it is not, go copy it from user space.
00053  */
00054   register char *rpu, *rpm;
00055   int r;
00056 
00057   /* Check name length for validity. */
00058   if (len <= 0) {
00059         err_code = EINVAL;
00060         return(EGENERIC);
00061   }
00062 
00063   if (len > PATH_MAX) {
00064         err_code = ENAMETOOLONG;
00065         return(EGENERIC);
00066   }
00067 
00068   if (flag == M3 && len <= M3_STRING) {
00069         /* Just copy the path from the message to 'user_path'. */
00070         rpu = &user_path[0];
00071         rpm = m_in.pathname;            /* contained in input message */
00072         do { *rpu++ = *rpm++; } while (--len);
00073         r = OK;
00074   } else {
00075         /* String is not contained in the message.  Get it from user space. */
00076         r = sys_datacopy(who_e, (vir_bytes) path,
00077                 FS_PROC_NR, (vir_bytes) user_path, (phys_bytes) len);
00078   }
00079   return(r);
00080 }
00081 
00082 /*===========================================================================*
00083  *                              no_sys                                       *
00084  *===========================================================================*/
00085 PUBLIC int no_sys()
00086 {
00087 /* Somebody has used an illegal system call number */
00088   return(EINVAL);
00089 }
00090 
00091 /*===========================================================================*
00092  *                              panic                                        *
00093  *===========================================================================*/
00094 PUBLIC void panic(who, mess, num)
00095 char *who;                      /* who caused the panic */
00096 char *mess;                     /* panic message string */
00097 int num;                        /* number to go with it */
00098 {
00099 /* Something awful has happened.  Panics are caused when an internal
00100  * inconsistency is detected, e.g., a programming error or illegal value of a
00101  * defined constant.
00102  */
00103   if (panicking) return;        /* do not panic during a sync */
00104   panicking = TRUE;             /* prevent another panic during the sync */
00105 
00106   printf("FS panic (%s): %s ", who, mess);
00107   if (num != NO_NUM) printf("%d",num); 
00108   (void) do_sync();             /* flush everything to the disk */
00109   sys_exit(SELF);
00110 }
00111 
00112 /*===========================================================================*
00113  *                              conv2                                        *
00114  *===========================================================================*/
00115 PUBLIC unsigned conv2(norm, w)
00116 int norm;                       /* TRUE if no swap, FALSE for byte swap */
00117 int w;                          /* promotion of 16-bit word to be swapped */
00118 {
00119 /* Possibly swap a 16-bit word between 8086 and 68000 byte order. */
00120   if (norm) return( (unsigned) w & 0xFFFF);
00121   return( ((w&BYTE) << 8) | ( (w>>8) & BYTE));
00122 }
00123 
00124 /*===========================================================================*
00125  *                              conv4                                        *
00126  *===========================================================================*/
00127 PUBLIC long conv4(norm, x)
00128 int norm;                       /* TRUE if no swap, FALSE for byte swap */
00129 long x;                         /* 32-bit long to be byte swapped */
00130 {
00131 /* Possibly swap a 32-bit long between 8086 and 68000 byte order. */
00132   unsigned lo, hi;
00133   long l;
00134   
00135   if (norm) return(x);                  /* byte order was already ok */
00136   lo = conv2(FALSE, (int) x & 0xFFFF);  /* low-order half, byte swapped */
00137   hi = conv2(FALSE, (int) (x>>16) & 0xFFFF);    /* high-order half, swapped */
00138   l = ( (long) lo <<16) | hi;
00139   return(l);
00140 }
00141 
00142 /*===========================================================================*
00143  *                              isokendpt_f                                  *
00144  *===========================================================================*/
00145 PUBLIC int isokendpt_f(char *file, int line, int endpoint, int *proc, int fatal)
00146 {
00147         int failed = 0;
00148         *proc = _ENDPOINT_P(endpoint);
00149         if(*proc < 0 || *proc >= NR_PROCS) {
00150                 printf("FS:%s:%d: proc (%d) from endpoint (%d) out of range\n",
00151                         file, line, *proc, endpoint);
00152                 failed = 1;
00153         } else if(fproc[*proc].fp_endpoint != endpoint) {
00154                 printf("FS:%s:%d: proc (%d) from endpoint (%d) doesn't match "
00155                         "known endpoint (%d)\n",
00156                         file, line, *proc, endpoint, fproc[*proc].fp_endpoint);
00157                 failed = 1;
00158         }
00159 
00160         if(failed && fatal)
00161                 panic(__FILE__, "isokendpt_f failed", NO_NUM);
00162 
00163         return failed ? EDEADSRCDST : OK;
00164 }
00165 

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