Beispiel #1
0
void
check_string(const void *ptr)
{
  check_ptr(ptr);
  check_ptr(*(char **)ptr);
  int i = 1;
  while (*(char *)(ptr + i) != '\0')
  {
    check_ptr(ptr+i);
    i++;
  }
}
Beispiel #2
0
/* Reads up to size bytes from the file open with descriptor fd into buffer,
   and returns the actual number of bytes read (may be less than size if EOF
   is reached), or -1 if no file is open as fd, or the read fails for any
   other reason.  Calling read with fd = 0 will read input from standard input,
   blocking until size bytes have been read */
static int
sys_read (int fd, void *buffer, unsigned size)
{
  check_ptr (buffer);
  
  unsigned read;
  struct file_fd *ffd;
  char *char_buffer = buffer;

  switch (fd) {
  case 0:
    for (read = 0; read < size; read++) {
      char_buffer[read] = input_getc ();
    }
    return read;
  case 1:
    return -1;
  case 2:
    return -1;
  default:
    ffd = get_file_fd (fd);
    if (ffd == NULL)
      return -1;
    lock_acquire (&fs_lock);
    read = file_read (ffd->file, buffer, size);
    lock_release (&fs_lock);
    return read;
  }
}
Beispiel #3
0
/* Writes up to size bytes from buffer to the file open with descriptor fd,
   and returns the actual number written (may be less than size if EOF is 
   reached), or -1 if no file is open as fd or the write fails for another
   reason.  Writing to 1 will print to standard output */
static int 
sys_write (int fd, const void *buffer, unsigned size) 
{
  int written;
  struct file_fd *ffd;
  
  check_ptr (buffer);
  
  switch (fd) {
  case 0:
    return 0;
  case 1:
    putbuf ((char *) buffer, size);
    return size;
  case 2:
    return 0;
  default:
    ffd = get_file_fd (fd);
    if (ffd == NULL)
      return 0;
    
    lock_acquire (&fs_lock);
    written = file_write (ffd->file, buffer, size);
    lock_release (&fs_lock);
    return written;
  }
}
int idaapi type_builder_t::visit_expr(cexpr_t *e)
{
	// check if the expression being visited is variable
	if(e->op == cot_var)
	{
		// get the variable name
		char expr_name[MAXSTR];
		e->print1(expr_name, MAXSTR, NULL);
        tag_remove(expr_name, expr_name, 0);

		// check for the target variable
		if(!strcmp(expr_name, highl_expr_name))
		{
			struct_filed str_fld;
			
			if(check_memptr(str_fld))
				structure.push_back(str_fld);
			else if(check_idx(str_fld))
				structure.push_back(str_fld);
			else if(check_ptr(str_fld))
				structure.push_back(str_fld);

		}
	}

	return 0;
}
int idaapi type_builder_t::visit_expr(cexpr_t *e)
{
	// check if the expression being visited is variable
	if(e->op == cot_var)
	{
		// get the variable name
		char expr_name[MAXSTR];
		e->print1(expr_name, MAXSTR, NULL);
        tag_remove(expr_name, expr_name, 0);

		// check for the target variable
		if(match_expression(expr_name))
		{
			struct_filed str_fld;

			if(check_ptr(e, str_fld)) {
				std::pair<std::map<int,struct_filed>::iterator,bool> ret;
				ret = structure.insert(std::pair<int,struct_filed>(str_fld.offset, str_fld));
				if ((ret.second == false) && (str_fld.vftbl != BADADDR)) {
					structure[str_fld.offset] = str_fld;
				}
			}
		}
	}

	return 0;
}
Beispiel #6
0
static xmlDocPtr merge_locale_trees_in_first(xmlDocPtr *tree_tab, int tree_num)
{
	xmlDocPtr new_tree;
	int i;

	if (tree_tab == NULL || tree_num == 0)
		return NULL;
		
	for(i = 0; i < tree_num; i++) {
		if (tree_tab[i] != NULL) {
			break;
		}
	}
	
	if (i == tree_num) {
		return NULL;
	}
		
	new_tree = xmlCopyDoc(tree_tab[i], 1);
	check_ptr(new_tree, "");
	
	if (tree_num > 0) {
		merge_trees(new_tree->children->children, &(tree_tab[i+1]), tree_num-i-1);
	}

	return new_tree;
}
void sb_set_open(void *new_open)
{
	if (!check_ptr(new_open))
		return;

	sbio_open = new_open;
}
Beispiel #8
0
void extract_params(struct intr_frame* f, const char* format, ...)
{
  va_list ap;
  va_start(ap, format);
  char *esp = (char*) f->esp + sizeof(int);
  char *str;
  void *buff;
  unsigned int size;
  while (format && *format) {
	  CHECK_ESP(esp);
    switch (*format) {
    case 'i': // int
      EXTRACT_PARAM(ap, esp, int);
      break;
    case 'u': // unsigned int
      EXTRACT_PARAM(ap, esp, unsigned int);
      break;
    case 's': // string (char*)
      POP_STACK_PARAM(esp, char*, str);
      check_str(str);
      ARG_PARAM(ap, void*) = str;
      break;
    case 'b': // buffer (void* + size_t)
      POP_STACK_PARAM(esp, void*, buff);
      POP_STACK_PARAM(esp, size_t, size);
      check_ptr(buff, size);
      ARG_PARAM(ap, void*) = buff;
      ARG_PARAM(ap, size_t) = size;
      break;
    }
    format++;
  }
  va_end(ap);
}
Beispiel #9
0
void _myfree(void *ptr, const char *filename, uint lineno, myf myflags)
{
  struct st_irem *irem;
  DBUG_ENTER("_myfree");
  DBUG_PRINT("enter",("ptr: %p", ptr));

  if (!sf_malloc_quick)
    (void) _sanity (filename, lineno);

  if ((!ptr && (myflags & MY_ALLOW_ZERO_PTR)) ||
      check_ptr("Freeing",(uchar*) ptr,filename,lineno))
    DBUG_VOID_RETURN;

  /* Calculate the address of the remember structure */
  irem= (struct st_irem *) ((char*) ptr- ALIGN_SIZE(sizeof(struct st_irem))-
			    sf_malloc_prehunc);

  /*
    Check to make sure that we have a real remember structure.
    Note: this test could fail for four reasons:
    (1) The memory was already free'ed
    (2) The memory was never new'ed
    (3) There was an underrun
    (4) A stray pointer hit this location
  */

  if (*((uint32*) ((char*) ptr- sizeof(uint32))) != MAGICKEY)
  {
    fprintf(stderr, "Error: Freeing unallocated data at line %d, '%s'\n",
	    lineno, filename);
    DBUG_PRINT("safe",("Unallocated data at line %d, '%s'",lineno,filename));
    (void) fflush(stderr);
    DBUG_VOID_RETURN;
  }

  /* Remove this structure from the linked list */
  pthread_mutex_lock(&THR_LOCK_malloc);
  if (irem->prev)
    irem->prev->next= irem->next;
   else
    sf_malloc_root= irem->next;

  if (irem->next)
    irem->next->prev= irem->prev;
  /* Handle the statistics */
  sf_malloc_cur_memory-= irem->datasize;
  sf_malloc_count--;
  pthread_mutex_unlock(&THR_LOCK_malloc);

#ifndef HAVE_purify
  /* Mark this data as free'ed */
  if (!sf_malloc_quick)
    bfill(ptr, irem->datasize, (pchar) FREE_VAL);
#endif
  *((uint32*) ((char*) ptr- sizeof(uint32)))= ~MAGICKEY;
  /* Actually free the memory */
  free((char*) irem);
  DBUG_VOID_RETURN;
}
Beispiel #10
0
void _myfree (gptr pPtr, const char *sFile, uint uLine, myf myflags)
{
  struct remember *pRec;
  DBUG_ENTER("_myfree");
  DBUG_PRINT("enter",("ptr: %lx",pPtr));

  if (!sf_malloc_quick)
    (void) _sanity (sFile, uLine);

  if ((!pPtr && (myflags & MY_ALLOW_ZERO_PTR)) ||
      check_ptr("Freeing",(byte*) pPtr,sFile,uLine))
    DBUG_VOID_RETURN;

  /* Calculate the address of the remember structure */
  pRec = (struct remember *) ((byte*) pPtr-sizeof(struct irem)-
			      sf_malloc_prehunc);

  /* Check to make sure that we have a real remember structure	*/
  /* Note: this test could fail for four reasons:		*/
  /*	(1) The memory was already free'ed			*/
  /*	(2) The memory was never new'ed				*/
  /*	(3) There was an underrun				*/
  /*	(4) A stray pointer hit this location			*/

  if (*((long*) ((char*) &pRec -> lSpecialValue+sf_malloc_prehunc))
      != MAGICKEY)
  {
    fprintf (stderr, "Freeing unallocated data at line %d, '%s'\n",
	     uLine, sFile);
    DBUG_PRINT("safe",("Unallocated data at line %d, '%s'",uLine,sFile));
    (void) fflush(stderr);
    DBUG_VOID_RETURN;
  }

  /* Remove this structure from the linked list */
  pthread_mutex_lock(&THR_LOCK_malloc);
  if (pRec -> pPrev) {
    pRec -> pPrev -> pNext = pRec -> pNext;
  } else {
    pRememberRoot = pRec -> pNext;
  }
  if (pRec -> pNext) {
    pRec -> pNext -> pPrev = pRec -> pPrev;
  }
  /* Handle the statistics */
  lCurMemory -= pRec -> uDataSize;
  cNewCount--;
  pthread_mutex_unlock(&THR_LOCK_malloc);

#ifndef HAVE_purify
  /* Mark this data as free'ed */
  bfill(&pRec->aData[sf_malloc_prehunc],pRec->uDataSize,(pchar) FREE_VAL);
#endif
  *((long*) ((char*) &pRec -> lSpecialValue+sf_malloc_prehunc)) = ~MAGICKEY;

  /* Actually free the memory */
  free ((my_string ) pRec);
  DBUG_VOID_RETURN;
}
Beispiel #11
0
DataObject::Ptr DomainObject::get_data_object(bool check) const
{
    if (owner_)
        return DataObject::get_master(owner_->get_data_object(check), prop_name_);
    if (check)
        check_ptr();
    return d_;
}
Beispiel #12
0
/* Gets the nth argument (starting with 1) to the system call off the stack,
   and verifies the pointer to make sure it is valid */
static void *
get_arg_ptr (void *esp, int n)
{
  void *result;
  result = (esp+(n*4));
  check_ptr (result);
  return result;
}
Beispiel #13
0
 bool merge(el<T>*ptr, list& other){
     if (check_ptr(ptr)) return false;
     if (other.head()==NULL) return false;
     ptr->next->prev =other.head()->prev;
     other.head()->prev->next = ptr->next;
     ptr->next = other.head();
     other.head()->prev = ptr;
     this->count_ += other.count_;
     other.head_ = NULL;
     return true;/*: data(dt)*/
 }
Beispiel #14
0
static char *create_content_list_file_path(char *scrollkeeper_dir, char *locale, 
						char *base)
{
	char *str;
		
	str = malloc(sizeof(char)*
			(strlen(scrollkeeper_dir)+1+strlen(locale)+1+strlen(base)+1));	
	check_ptr(str, "");
	
	sprintf(str, "%s/%s/%s", scrollkeeper_dir, locale, base);
	
	return str;
}
Beispiel #15
0
/* Creates a new file in the file system with the name file that is
   initial_size bytes long.  Returns a bool indicating if the file
   creation was successful */
static bool
sys_create (const char *file, unsigned initial_size)
{
  bool success;

  check_ptr (file);
  
  lock_acquire (&fs_lock);
  success = filesys_create (file, initial_size);
  lock_release (&fs_lock);
  
  return success;
}
Beispiel #16
0
/* Tries to remove the file with name "file" from the filesystem and returns
   whether or not the remove was successful.  A removed file will remain
   usable in any process that has it open when it is removed, until that 
   process closes the file */
static bool
sys_remove (const char *file)
{
  bool success;

  check_ptr (file);

  lock_acquire (&fs_lock);
  success = filesys_remove (file);
  lock_release (&fs_lock);

  return success;
}
Beispiel #17
0
bool
__check_arg_ptr (const void *ptr, const char *file, const char *func, size_t line)
{
  if (!check_ptr (ptr))
    {
      rc_errno_set (EINVAL);

      debug_message (file, func, line, "Invalid pointer passed!\n");

      return false;
    }

  return true;
}
Beispiel #18
0
/* Creates a new process running the program specified in cmd_line,
   and returns the pid (which maps one-to-one to the thread's tid) of
   the new process or -1 if the process could not be successfully loaded.  
   Will not return until the child has completed loading */
static tid_t
sys_exec (const char *cmd_line)
{
  tid_t tid = 0;
  check_ptr (cmd_line);
  
  lock_acquire (&fs_lock);
  tid = process_execute (cmd_line);
  lock_release (&fs_lock);
  sema_down (&thread_current ()->exec_sema);
  if (thread_current ()->child_successful) {
    thread_current ()->child_successful = false;
    return tid;
  }
  return -1;
}
Beispiel #19
0
void
check_buffer(const void *ptr, unsigned size)
{
  int i;
  check_ptr(*(char**)ptr);
  for (i = 0; i < size; i++)
  {
    // check_ptr(ptr + i);
    if ( (ptr+i) == NULL ||
      pagedir_get_page(thread_current()->pagedir, ptr) == NULL )
    {
      exit(-1);
    }
  }

}
Beispiel #20
0
gptr _myrealloc (register gptr pPtr, register uint uSize,
		 const char *sFile, uint uLine, myf MyFlags)
{
  struct remember *pRec;
  gptr ptr;
  DBUG_ENTER("_myrealloc");

  if (!pPtr && (MyFlags & MY_ALLOW_ZERO_PTR))
    DBUG_RETURN(_mymalloc(uSize,sFile,uLine,MyFlags));

  if (!sf_malloc_quick)
    (void) _sanity (sFile, uLine);

  if (check_ptr("Reallocating",(byte*) pPtr,sFile,uLine))
    DBUG_RETURN((gptr) NULL);

  pRec = (struct remember *) ((char*) pPtr - sizeof (struct irem)-
			      sf_malloc_prehunc);
  if (*((long*) ((char*) &pRec -> lSpecialValue+sf_malloc_prehunc))
      != MAGICKEY)
  {
    fprintf (stderr, "Reallocating unallocated data at line %d, '%s'\n",
	     uLine, sFile);
    DBUG_PRINT("safe",("Reallocating unallocated data at line %d, '%s'",
		       uLine, sFile));
    (void) fflush(stderr);
    DBUG_RETURN((gptr) NULL);
  }

  if ((ptr=_mymalloc(uSize,sFile,uLine,MyFlags)))	/* Allocate new area */
  {
    uSize=min(uSize,pRec-> uDataSize);		/* Move as much as possibly */
    memcpy((byte*) ptr,pPtr,(size_t) uSize);	/* Copy old data */
    _myfree(pPtr,sFile,uLine,0);		/* Free not needed area */
  }
  else
  {
    if (MyFlags & MY_HOLD_ON_ERROR)
      DBUG_RETURN(pPtr);
    if (MyFlags & MY_FREE_ON_ERROR)
      _myfree(pPtr,sFile,uLine,0);
  }
  DBUG_RETURN(ptr);
} /* _myrealloc */
Beispiel #21
0
void *_myrealloc(register void *ptr, register size_t size,
                 const char *filename, uint lineno, myf MyFlags)
{
  struct st_irem *irem;
  char *data;
  DBUG_ENTER("_myrealloc");

  if (!ptr && (MyFlags & MY_ALLOW_ZERO_PTR))
    DBUG_RETURN(_mymalloc(size, filename, lineno, MyFlags));

  if (!sf_malloc_quick)
    (void) _sanity (filename, lineno);

  if (check_ptr("Reallocating", (uchar*) ptr, filename, lineno))
    DBUG_RETURN((uchar*) NULL);

  irem= (struct st_irem *) (((char*) ptr) - ALIGN_SIZE(sizeof(struct st_irem))-
			    sf_malloc_prehunc);
  if (*((uint32*) (((char*) ptr)- sizeof(uint32))) != MAGICKEY)
  {
    fprintf(stderr, "Error: Reallocating unallocated data at line %d, '%s'\n",
	    lineno, filename);
    DBUG_PRINT("safe",("Reallocating unallocated data at line %d, '%s'",
		       lineno, filename));
    (void) fflush(stderr);
    DBUG_RETURN((uchar*) NULL);
  }

  if ((data= _mymalloc(size,filename,lineno,MyFlags))) /* Allocate new area */
  {
    size=min(size, irem->datasize);		/* Move as much as possibly */
    memcpy((uchar*) data, ptr, (size_t) size);	/* Copy old data */
    _myfree(ptr, filename, lineno, 0);		/* Free not needed area */
  }
  else
  {
    if (MyFlags & MY_HOLD_ON_ERROR)
      DBUG_RETURN(ptr);
    if (MyFlags & MY_FREE_ON_ERROR)
      _myfree(ptr, filename, lineno, 0);
  }
  DBUG_RETURN(data);
} /* _myrealloc */
Beispiel #22
0
/* Opens the file with the name "file", and returns its file descriptor.
   Returns -1 if no such file exists, or if the open fails for any other
   reason.  If the same file is opened multiple times by separate processes
   or the same process, different fds with separate file pointers will be
   returned */
static int 
sys_open (const char *file)
{
  struct file *f;
  struct file_fd *ffd;
  check_ptr (file);
  
  lock_acquire (&fs_lock);
  f = filesys_open (file);
  lock_release (&fs_lock);

  if (f == NULL)
    return -1;
  ffd = malloc (sizeof(struct file_fd));
  ffd->file = f;
  ffd->fd = thread_current ()->next_fd++;
  list_push_back (&thread_current ()->open_files, &ffd->elem);

  return ffd->fd;
}
Beispiel #23
0
static void merge_two_sections(xmlNodePtr sect_node, xmlNodePtr other_sect_node)
{
	xmlNodePtr node, new_node;
	xmlChar *uid;
	
	for(node = other_sect_node->children; node != NULL; node = node->next) {
		if (xmlStrcmp(node->name, (xmlChar *)"doc")) {
			continue;
		}
	
		uid = get_doc_uid(node);
		if (uid != NULL) {
			if (!find_uid_in_sect(sect_node, uid)) {
				new_node = xmlCopyNode(node, 1);
				check_ptr(new_node, "");
				xmlAddChild(sect_node, new_node);
			}
		}
	}
}
Beispiel #24
0
// message array constructor
static
const fix_message_data* make_n_messages(const unsigned n, char** str, unsigned* psize)
{
	fix_message_data* const orders = check_ptr(malloc(n * sizeof(fix_message_data)));
	char* s;
	size_t size;
	FILE* const builder = open_memstream(&s, &size);

	ASSURE(builder);

	for(unsigned i = 0; i < n; ++i)
	{
		gen_new_order_single(orders + i);
		message_to_string(builder, orders + i);
	}

	ASSURE(fclose(builder) == 0);
	*str = s;
	*psize = size;
	return orders;
}
//Extract number's information into the defined number structure
numType *extract(int input)
{
	numType *n = NULL;
	int i;
	n = malloc(sizeof(numType));
	check_ptr(n);

	//Store the number's sign and number of digits
	if (input < 0)
	{
		n->sign = -1;
		input *= -1;
		n->digits = digits(input);
	} else
	{
		n->sign = 1;
		n->digits = digits(input);
	}

	/*Store each digit into an array's element*/
	//Initialize the array member in the structure
	n->number = NULL;
	n->number = calloc(digits(input), sizeof(int));
	if (n->number == NULL)
	{
		fprintf(stderr, "Error creating array!");
		exit(1);
	}
	//Storing digits
	for (i = digits(input) - 1; i >= 0; i--)
	{
		(n->number)[i] = input % 10;
		input /= 10;
	}

	return n;
}
Beispiel #26
0
static void
syscall_handler (struct intr_frame *f) 
{
  int *sys_call;

  int *status;

  int *fd;
  const char **buf;
  int *size;

  const char **file;

  tid_t *pid;

  const char **cmd_line;

  unsigned *initial_size;

  unsigned *position;

  void **buffer;

  sys_call = (int*) f->esp;
  check_ptr(sys_call);

  switch(*sys_call) {
  case SYS_HALT:
    sys_halt ();
    break;
  case SYS_EXIT:
    status = (int *) get_arg_ptr (f->esp, 1);
    sys_exit(*status);
    NOT_REACHED();
    break;
  case SYS_EXEC:
    cmd_line = (const char **) get_arg_ptr (f->esp, 1);
    f->eax = sys_exec (*cmd_line);
    break;
  case SYS_WAIT:
    pid = (tid_t *) get_arg_ptr (f->esp, 1);
    f->eax = sys_wait (*pid);
    break;
  case SYS_CREATE:
    file = (const char **) get_arg_ptr (f->esp, 1);
    initial_size = (unsigned *) get_arg_ptr (f->esp, 2);
    f->eax = sys_create (*file, *initial_size);
    break;
  case SYS_REMOVE:
    file = (const char **) get_arg_ptr (f->esp, 1);
    f->eax = sys_remove (*file);
    break;
  case SYS_OPEN:
    file = (const char **) get_arg_ptr(f->esp, 1);
    f->eax = sys_open (*file);
    break;
  case SYS_FILESIZE:
    fd = (int *) get_arg_ptr (f->esp, 1);
    f->eax = sys_filesize (*fd);
    break;
  case SYS_READ:
    fd = (int *) get_arg_ptr (f->esp, 1);
    buffer = (void **) get_arg_ptr (f->esp, 2);
    size = (int *) get_arg_ptr (f->esp, 3);
    f->eax = sys_read (*fd, *buffer, *size);
    break;
  case SYS_WRITE:
    fd = (int *) get_arg_ptr (f->esp, 1);
    buf = (const void **) get_arg_ptr (f->esp, 2);
    size = (int *) get_arg_ptr (f->esp, 3);
    f->eax = sys_write (*fd, *buf, *size);
    break;
  case SYS_SEEK:
    fd = (int *) get_arg_ptr (f->esp, 1);
    position = (unsigned *) get_arg_ptr (f->esp, 2);
    sys_seek (*fd, *position);
    break;
  case SYS_TELL:
    fd = (int *) get_arg_ptr (f->esp, 1);
    f->eax = sys_tell (*fd);
    break;
  case SYS_CLOSE:
    fd = (int *) get_arg_ptr (f->esp, 1);
    sys_close (*fd);
    break;
  default:
    printf ("Unrecognized system call!\n");
    thread_exit ();
  }
}
Beispiel #27
0
static void
syscall_handler (struct intr_frame *f)
{
  uint32_t *p = f->esp;
  check_ptr(p);
  switch (*(int *)p)
  {
  /* Halt the operating system.
    IN : void
    OUT: void
  */
  case SYS_HALT:
  {
    shutdown_power_off();
    break;
  }

  /* Terminate this process.
    IN : int status
    OUT: void
  */
  case SYS_EXIT:
  {
    check_ptr(p + 1);
    int status = *(int *)(p + 1);
    exit(status);
    break;
  }


  /* Start another process.
    IN : const char *file
    OUT: pid_t
  */
  case SYS_EXEC:
  {
    check_string(p + 1);
    // f->eax = process_execute(*(char **)(p + 1));
    pid_t pid = process_execute(*(char **)(p + 1));
    struct child_process *cp = get_child_process(pid);
    if(cp->load == LOAD_SUCCESS)
      f->eax = pid;
    else if(cp->load == LOAD_FAIL)
      f->eax = -1;
    break;
  }

  /* Wait for a child process to die.
    IN : pid_t
    OUT: int
  */
  case SYS_WAIT:
  {
    check_ptr(p + 1);
    f->eax = process_wait(*(tid_t *)(p + 1));
    break;
  }

  /* Create a file.
    IN :const char *file, unsigned initial_size
    OUT:bool
  */
  case SYS_CREATE:
  {
    check_string(p + 1);
    check_ptr(p + 2);
    if(*(char**)(p+1)==NULL||*(int *)(p+1)>=PHYS_BASE||
      pagedir_get_page(thread_current()->pagedir, (const void *)*(p+1)) == NULL)
      exit(-1);
    
    f->eax = filesys_create(*(const char **)(p + 1), *(off_t *)(p + 2));
    
    break;
  }

  /* Delete a file.
    IN: const char *file
    OUT: bool
  */
  case SYS_REMOVE:
  {

    check_string(p + 1);
    if(*(char**)(p+1)==NULL||*(int *)(p+1)>=PHYS_BASE||
      pagedir_get_page(thread_current()->pagedir, (const void *)*(p+1)) == NULL)
      exit(-1);
    
    f->eax = filesys_remove(*(char**)(p + 1));
    break;
  }

  /* Open a file.
    IN: const char *file
    OUT: int
  */
  case SYS_OPEN:
  {
    check_string(p + 1);
    
    struct file *file = filesys_open(*(char**)(p + 1));
    if (file == NULL)
    {
      f->eax = -1;
      break;
    }
    struct file_desc *desc = malloc(sizeof(struct file_desc));
    desc->file = file;
    desc->fd = thread_current()->fd;
    thread_current()->fd++;
    list_push_back(&thread_current()->file_list, &desc->elem);
    f->eax = desc->fd;
    break;
  }

  /* Obtain a file's size.
    IN: int fd
    OUT: int
  */
  case SYS_FILESIZE:
  {
    check_ptr(p + 1);
    int fd = *(p + 1);
    
    struct file *file = process_get_file(fd);
    if (file == NULL)
    {
      f->eax = FILE_ERROR;
    }
    else
    {
      f->eax = file_length(file);
    }
    break;
  }

  /* Read from a file.
    IN: int fd, void *buffer, unsigned length
    OUT: int
  */
  case SYS_READ:
  {
    check_ptr(p + 1);
    check_ptr(p + 2);
    check_ptr(p + 3);
    check_buffer(p + 2, *(p + 3));

    int fd = *(int *)(p + 1);
    void *buffer = *(char**)(p + 2);
    unsigned length = *(unsigned *)(p + 3);

    //read from keyboard. Fd 0 reads from keyboard using input_getc(): one each time.
    if (fd == STDIN_FILENO)
    {
      uint8_t *into_buffer = (uint8_t *) buffer;
      unsigned i;
      for (i = 0; i < length; i++)
      {
        into_buffer[i] = input_getc();
      }
      f->eax = length;
    }
    else
    {
      //read from file into buffer
      
      struct file *file = process_get_file(fd);
      //return -1 if file couldn't be read.
      if (file == NULL)
      {
            f->eax = FILE_ERROR;  //-1
      }
      else
      {
        int bytes = file_read(file, buffer, length);
            f->eax = bytes;
      }

    }
    break;
  }

  /* Write to a file.
    IN: int fd, const void *buffer, unsigned length
    OUT: int
  */
  case SYS_WRITE:
  {
    check_ptr(p + 1);
    check_ptr(p + 2);
    check_ptr(p + 3);
    check_buffer(p + 2, *(p + 3));

    int fd = *(int *)(p + 1);
    void *buffer = *(char**)(p + 2);
    unsigned length = *(off_t *)(p + 3);
    if (length <= 0)
    {
      f->eax = 0;
      break;
    }
    //Fd=1(STDOUT_FILENO) writes to the console.
    if (fd == STDOUT_FILENO)
    {
      putbuf(buffer, length);
      f->eax = length;
    }
    else
    {
      // return file by file descriptor.
      struct file *file = process_get_file(fd);
      if (file == NULL)
      {
            f->eax = FILE_ERROR;  //-1
      }
      else
      {
        int bytes = file_write(file, buffer, length);
        f->eax = bytes;
      }
    }
    break;
  }

  /* Change position in a file.
    IN: int fd, unsigned position
    OUT: void
  */
  case SYS_SEEK:
  {
    check_ptr(p + 1);
    check_ptr(p + 2);
    int fd = *(int *)(p+1);
    unsigned position = *(unsigned *)(p+2);
    
    struct file *file = process_get_file(fd);
    if(file != NULL)
    {
      file_seek(file, position);
    }
    break;
  }

  /* Report current position in a file.
    IN: int fd
    OUT: unsigned
  */
  case SYS_TELL:
  {
    check_ptr(p + 1);
    int fd = *(int *)(p+1);

    
    struct file *file = process_get_file(fd);
    if(file != NULL)
    {
      f->eax = file_tell(file);
    }
    else
      f->eax = FILE_ERROR;  //-1
    break;
  }

  /* Close a file.
    IN: int fd
    OUT: void
  */
  case SYS_CLOSE:
  {
    check_ptr(p+1);
    int fd = *(int*)(p+1);
    
    struct thread *t = thread_current();
    struct list_elem *next, *e = list_begin(&t->file_list);
    while (e != list_end (&t->file_list))
    {
      next = list_next(e);
      struct file_desc *fl = list_entry (e, struct file_desc, elem);
      if (fd == fl->fd)
      {
        file_close(fl->file);
        list_remove(&fl->elem);
        free(fl);
        break;
      }
      e = next;
    }
    break;
  }

  default:
    break;
  }

}