/* 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 . */
#include
#include
#include
#include
#include
#include
#include
#include
#include
/* 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);
}