Minix1.5/fs/utility.c

Compare this file to the similar file:
Show the results in this format:

/* This file contains a few general purpose utility routines.
 *
 * The entry points into this file are
 *   clock_time:  ask the clock task for the real time
 *   copy:	  copy a block of data
 *   fetch_name:  go get a path name from user space
 *   no_sys:      reject a system call that FS does not handle
 *   panic:       something awful has occurred;  MINIX cannot continue
 */

#include "fs.h"
#include <minix/com.h>
#include <minix/boot.h>
#include "buf.h"
#include "file.h"
#include "fproc.h"
#include "inode.h"
#include "param.h"
#include "super.h"

PRIVATE int panicking;		/* inhibits recursive panics during sync */
PRIVATE message clock_mess;

/*===========================================================================*
 *				clock_time				     *
 *===========================================================================*/
PUBLIC time_t clock_time()
{
/* This routine returns the time in seconds since 1.1.1970.  MINIX is an
 * astrophysically naive system that assumes the earth rotates at a constant
 * rate and that such things as leap seconds do not exist.
 */

  register int k;
  register struct super_block *sp;

  clock_mess.m_type = GET_TIME;
  if ( (k = sendrec(CLOCK, &clock_mess)) != OK) panic("clock_time err", k);

  /* Since we now have the time, update the super block.  It is almost free. */
  sp = get_super(ROOT_DEV);
  if (sp) {
	sp->s_time = clock_mess.NEW_TIME;	/* update super block time */
	if (sp->s_rd_only == FALSE) sp->s_dirt = DIRTY;
  }

  return (time_t) clock_mess.NEW_TIME;
}


/*===========================================================================*
 *				copy					     *
 *===========================================================================*/
PUBLIC void copy(dest, source, bytes)
char *dest;			/* destination pointer */
char *source;			/* source pointer */
int bytes;			/* how much data to move */
{
/* Copy a byte string of length 'bytes' from 'source' to 'dest'.
 * If all three parameters are exactly divisible by the integer size, copy them
 * an integer at a time.  Otherwise copy character-by-character.
 */

  int src, dst;

  if (bytes <= 0) return;	/* makes test-at-the-end possible */
  src = (int) source;		/* only low-order bits needed */	
  dst = (int) dest;		/* only low-order bits needed */

  if (bytes % sizeof(int) == 0 && src % sizeof(int) == 0 &&
						dst % sizeof(int) == 0) {
	/* Copy the string an integer at a time. */
	register int n = bytes/sizeof(int);
	register int *dpi = (int *) dest;
	register int *spi = (int *) source;

	do { *dpi++ = *spi++; } while (--n);

  } else {

	/* Copy the string character-by-character. */
	register int n = bytes;
	register char *dpc = (char *) dest;
	register char *spc = (char *) source;

	do { *dpc++ = *spc++; } while (--n);

  }
}


/*===========================================================================*
 *				fetch_name				     *
 *===========================================================================*/
PUBLIC int fetch_name(path, len, flag)
char *path;			/* pointer to the path in user space */
int len;			/* path length, including 0 byte */
int flag;			/* M3 means path may be in message */
{
/* Go get path and put it in 'user_path'.
 * If 'flag' = M3 and 'len' <= M3_STRING, the path is present in 'message'.
 * If it is not, go copy it from user space.
 */

  register char *rpu, *rpm;
  vir_bytes vpath;

  if (len <= 0) {
	err_code = EINVAL;
	return(ERROR);
  }
  if (flag == M3 && len <= M3_STRING) {
	/* Just copy the path from the message to 'user_path'. */
	rpu = &user_path[0];
	rpm = pathname;		/* contained in input message */
	do { *rpu++ = *rpm++; } while (--len);
	return(OK);
  }

  /* String is not contained in the message.  Go get it from user space. */
  if (len > PATH_MAX) {
	err_code = ENAMETOOLONG;
	return(ERROR);
  }
  vpath = (vir_bytes) path;
  err_code = rw_user(D, who, vpath, (vir_bytes) len, user_path, FROM_USER);
  return(err_code);
}


/*===========================================================================*
 *				no_sys					     *
 *===========================================================================*/
PUBLIC int no_sys()
{
/* Somebody has used an illegal system call number */

  return(EINVAL);
}


/*===========================================================================*
 *				panic					     *
 *===========================================================================*/
PUBLIC void panic(format, num)
char *format;			/* format string */
int num;			/* number to go with format string */
{
/* Something awful has happened.  Panics are caused when an internal
 * inconsistency is detected, e.g., a programming error or illegal value of a
 * defined constant.
 */

  if (panicking) return;	/* do not panic during a sync */
  panicking = TRUE;		/* prevent another panic during the sync */
  printf("File system panic: %s ", format);
  if (num != NO_NUM) printf("%d",num); 
  printf("\n");
  (void) do_sync();			/* flush everything to the disk */
  sys_abort();
}