View of xos/kernel/string_table.c


XOS | Parent Directory | View | Download

/* Copyright (C) 2008  Emmanuel Varoquaux
 
   This file is part of XOS.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
 
   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
 
#include <kmalloc.h>
#include <verify_area.h>
#include <string_table_struct.h>
#include <segment.h>
#include <errno.h>
#include <enums.h>
#include <config.h>
#include <string.h>
#include <stddef.h>
 
/* Constructeur a partir d'une chaine de caracteres dans l'espace noyau. */
int string_table_init_from_string(struct string_table_struct *string_table, const char *str)
{
  unsigned int size;
 
  size = strlen(str) + 2;
 
  string_table->count = 1;
  if (!(string_table->buf = kmalloc(size)))
    return -ENOMEM;
  strcpy(string_table->buf, str);
  string_table->buf[size - 1] = '\0';
  string_table->size = size;
  return 0;
}
 
/* Constructeur a partir d'un tableau de chaines de caracteres dans l'espace utilisateur. */
int string_table_init_from_array(struct string_table_struct *string_table, char *const fs_str_array[])
{
  unsigned int count;
  unsigned int size;
  int i;
  unsigned int len;
  char *p;
  const char *fs_s;
 
  count = 0;
  size = 0;
  i = 0;
  if (!verify_area(&fs_str_array[0], sizeof (long), PF_READ))
    return -EFAULT;
  while (get_fs_long((const long *)&fs_str_array[i])) {
    if (!verify_str((char *)get_fs_long((const long *)&fs_str_array[i]), ARG_MAX_STRLEN, &len))
      return -EFAULT;
    if (len == ARG_MAX_STRLEN)
      return -E2BIG;
    count++;
    size += len + 1;
    i++;
    if (!verify_area(&fs_str_array[i], sizeof (long), PF_READ))
      return -EFAULT;
  }
 
  string_table->count = count;
  if (size) {
    size++;
    if (!(string_table->buf = kmalloc(size)))
      return -ENOMEM;
    i = 0;
    p = string_table->buf;
    while ((fs_s = (char *)get_fs_long((const long *)&fs_str_array[i]))) {
      while ((*p++ = get_fs_byte(fs_s++)));
      i++;
    }
    *p = '\0';
    string_table->size = size;
  }
  else {
    string_table->buf = NULL;
    string_table->size = 0;
  }
  return 0;
}
 
int string_table_clone(const struct string_table_struct *src_string_table, struct string_table_struct *dest_string_table)
{
  dest_string_table->count = src_string_table->count;
  if (src_string_table->buf) {
    if (!(dest_string_table->buf = kmalloc(src_string_table->size)))
      return -ENOMEM;
    memcpy(dest_string_table->buf, src_string_table->buf, src_string_table->size);
  }
  else
    dest_string_table->buf = NULL;
  dest_string_table->size = src_string_table->size;
  return 0;
}
 
void string_table_destroy(struct string_table_struct *string_table)
{
  if (string_table->buf)
    kfree(string_table->buf, string_table->size);
}