1997-11-24 03:01  Ulrich Drepper  <drepper@cygnus.com>

	* elf/dl-support.c: Call __libc_init_secure to make sure
	__libc_enable_secure is defined early.
	* sysdeps/generic/enbl-secure.c: Change function name to
	__libc_init_secure and make it global instead of a constructor.

	* iconv/gconv.c: Fix lots of bugs.
	* iconv/gconv.h: Likewise.
	* iconv/gconv_builtin.h: Likewise.
	* iconv/gconv_close.c: Likewise.
	* iconv/gconv_conf.c: Likewise.
	* iconv/gconv_db.c: Likewise.
	* iconv/gconv_dl.c: Likewise.
	* iconv/gconv_open.c: Likewise.
	* iconv/gconv_simple.c: Likewise.
	* iconv/iconv.c: Likewise.
	* iconv/iconv_close.c: Likewise.
	* iconv/iconv_open.c: Likewise.

	* wcsmbs/Makefile (routines): Add wmemrtowcs and wmemrtombs.
	* wcsmbs/wchar.h: Add prototypes for wmemrtowcs and wmemrtombs.
	* wcsmbs/wmemrtombs.c: New file.
	* wcsmbs/wmemrtowcs.c: New file.
This commit is contained in:
Ulrich Drepper 1997-11-24 02:08:40 +00:00
parent f43ce637b5
commit e34b0f2902
19 changed files with 521 additions and 132 deletions

View file

@ -1,3 +1,28 @@
1997-11-24 03:01 Ulrich Drepper <drepper@cygnus.com>
* elf/dl-support.c: Call __libc_init_secure to make sure
__libc_enable_secure is defined early.
* sysdeps/generic/enbl-secure.c: Change function name to
__libc_init_secure and make it global instead of a constructor.
* iconv/gconv.c: Fix lots of bugs.
* iconv/gconv.h: Likewise.
* iconv/gconv_builtin.h: Likewise.
* iconv/gconv_close.c: Likewise.
* iconv/gconv_conf.c: Likewise.
* iconv/gconv_db.c: Likewise.
* iconv/gconv_dl.c: Likewise.
* iconv/gconv_open.c: Likewise.
* iconv/gconv_simple.c: Likewise.
* iconv/iconv.c: Likewise.
* iconv/iconv_close.c: Likewise.
* iconv/iconv_open.c: Likewise.
* wcsmbs/Makefile (routines): Add wmemrtowcs and wmemrtombs.
* wcsmbs/wchar.h: Add prototypes for wmemrtowcs and wmemrtombs.
* wcsmbs/wmemrtombs.c: New file.
* wcsmbs/wmemrtowcs.c: New file.
1997-11-22 19:28 Ulrich Drepper <drepper@cygnus.com>
* iconv/gconv_simple.c: Fix lots of bugs.

View file

@ -46,6 +46,8 @@ struct r_search_path *_dl_search_paths;
const char *_dl_profile;
struct link_map *_dl_profile_map;
extern void __libc_init_secure (void);
static void non_dynamic_init (void) __attribute__ ((unused));
@ -54,6 +56,10 @@ non_dynamic_init (void)
{
_dl_verbose = *(getenv ("LD_WARN") ?: "") == '\0' ? 0 : 1;
_dl_pagesize = __getpagesize ();
__libc_init_secure ();
/* Initialize the data structures for the search paths for shared
objects. */
_dl_init_paths ();
@ -65,7 +71,5 @@ non_dynamic_init (void)
/* Now determine the length of the platform string. */
if (_dl_platform != NULL)
_dl_platformlen = strlen (_dl_platform);
_dl_pagesize = __getpagesize ();
}
text_set_element (__libc_subinit, non_dynamic_init);

View file

@ -30,6 +30,9 @@ __gconv (gconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf,
size_t oldinbytes = *inbytesleft;
int result;
if (cd == (gconv_t) -1L)
return GCONV_ILLEGAL_DESCRIPTOR;
cd->data[last_step].outbuf = *outbuf;
cd->data[last_step].outbufavail = 0;
cd->data[last_step].outbufsize = *outbytesleft;

View file

@ -37,6 +37,7 @@ enum
GCONV_EMPTY_INPUT,
GCONV_FULL_OUTPUT,
GCONV_ILLEGAL_INPUT,
GCONV_INCOMPLETE_INPUT,
GCONV_ILLEGAL_DESCRIPTOR,
GCONV_INTERNAL_ERROR

View file

@ -18,17 +18,17 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
BUILTIN_TRANSFORMATION ("\\([^/]+\\)/UCS4/\\([^/]*\\)", NULL, 0,
BUILTIN_TRANSFORMATION ("([^/]+)/UCS4/([^/]*)", NULL, 0,
"\\1/UTF8/\\2", 1, "=ucs4->utf8",
__gconv_transform_ucs4_utf8,
__gconv_transform_init_rstate,
__gconv_transform_end_rstate)
BUILTIN_TRANSFORMATION ("\\([^/]+\\)/UTF8/\\([^/]*\\)", NULL, 0,
BUILTIN_TRANSFORMATION ("([^/]+)/UTF8/([^/]*)", NULL, 0,
"\\1/UCS4/\\2", 1, "=utf8->ucs4",
__gconv_transform_utf8_ucs4,
__gconv_transform_init_rstate,
__gconv_transform_end_rstate)
BUILTIN_TRANSFORMATION ("\\(.*\\)", NULL, 0, "\\1", 1, "=dummy",
BUILTIN_TRANSFORMATION ("(.*)", NULL, 0, "\\1", 1, "=dummy",
__gconv_transform_dummy, NULL, NULL)

View file

@ -48,9 +48,8 @@ __gconv_close (gconv_t cd)
/* Next step. */
++srunp;
++drunp;
}
while (!drunp->is_last);
while (!(drunp++)->is_last);
/* Save the pointer, we need it below. */
srunp = cd->steps;

View file

@ -19,6 +19,7 @@
Boston, MA 02111-1307, USA. */
#include <ctype.h>
#include <errno.h>
#include <gconv.h>
#include <search.h>
#include <stdio.h>
@ -35,6 +36,12 @@ static const char default_gconv_path[] = GCONV_PATH;
along the path. */
static const char gconv_conf_filename[] = "gconv-modules";
/* Filename extension for the modules. */
#ifndef MODULE_EXT
# define MODULE_EXT ".so"
#endif
static const char gconv_module_ext[] = MODULE_EXT;
/* We have a few builtin transformations. */
static struct gconv_module builtin_modules[] =
{
@ -111,15 +118,18 @@ add_alias (char *rp)
new_alias = (struct gconv_alias *)
malloc (sizeof (struct gconv_alias) + (wp - from));
new_alias->fromname = memcpy ((char *) new_alias
+ sizeof (struct gconv_alias),
from, to - from);
new_alias->toname = memcpy ((char *) new_alias + sizeof (struct gconv_alias)
+ (to - from), to, wp - to);
if (new_alias != NULL)
{
new_alias->fromname = memcpy ((char *) new_alias
+ sizeof (struct gconv_alias),
from, wp - from);
new_alias->toname = new_alias->fromname + (to - from);
if (__tsearch (new_alias, &__gconv_alias_db, __gconv_alias_compare) == NULL)
/* Something went wrong, free this entry. */
free (new_alias);
if (__tsearch (new_alias, &__gconv_alias_db, __gconv_alias_compare)
== NULL)
/* Something went wrong, free this entry. */
free (new_alias);
}
}
@ -138,6 +148,7 @@ add_module (char *rp, const char *directory, size_t dir_len, void **modules,
char *from, *to, *module, *wp;
size_t const_len;
int from_is_regex;
int need_ext;
int cost;
while (isspace (*rp))
@ -195,65 +206,68 @@ add_module (char *rp, const char *directory, size_t dir_len, void **modules,
/* Increment by one for the slash. */
++dir_len;
/* See whether we must add the ending. */
need_ext = 0;
if (wp - module < sizeof (gconv_module_ext)
|| memcmp (wp - sizeof (gconv_module_ext), gconv_module_ext,
sizeof (gconv_module_ext)) != 0)
/* We must add the module extension. */
need_ext = sizeof (gconv_module_ext) - 1;
/* We've collected all the information, now create an entry. */
const_len = 0;
if (from_is_regex)
do
++const_len;
while (isalnum (from[const_len]) || from[const_len] == '-'
|| from[const_len] == '/' || from[const_len] == '.'
|| from[const_len] == '_');
{
const_len = 0;
while (isalnum (from[const_len]) || from[const_len] == '-'
|| from[const_len] == '/' || from[const_len] == '.'
|| from[const_len] == '_')
++const_len;
}
else
const_len = to - from - 1;
new_module = (struct gconv_module *) malloc (sizeof (struct gconv_module)
+ (wp - from) + const_len
+ dir_len);
+ (wp - from)
+ dir_len + need_ext);
if (new_module != NULL)
{
char *tmp;
new_module->from_constpfx = memcpy ((char *) new_module
+ sizeof (struct gconv_module),
from, to - from);
if (from_is_regex)
{
new_module->from_pattern = memcpy ((char *) new_module
+ sizeof (struct gconv_module),
from, to - from);
new_module->from_constpfx = memcpy ((char *) new_module->from_pattern
+ (to - from),
from, const_len);
((char *) new_module->from_constpfx)[const_len] = '\0';
new_module->from_constpfx_len = const_len;
++const_len;
}
new_module->from_pattern = new_module->from_constpfx;
else
{
new_module->from_pattern = NULL;
new_module->from_constpfx = memcpy ((char *) new_module
+ sizeof (struct gconv_module),
from, to - from);
new_module->from_constpfx_len = to - from - 1;
const_len = to - from;
}
new_module->from_pattern = NULL;
new_module->from_constpfx_len = const_len;
new_module->from_regex = NULL;
new_module->to_string = memcpy ((char *) new_module->from_constpfx
+ const_len + 1, to, module - to);
+ (to - from), to, module - to);
new_module->cost = cost;
new_module->module_name = (char *) new_module->to_string + (module - to);
if (dir_len == 0)
new_module->module_name = memcpy ((char *) new_module->to_string
+ (module - to),
module, wp - module);
tmp = (char *) new_module->module_name;
else
{
char *tmp;
new_module->module_name = ((char *) new_module->to_string
+ (module - to));
tmp = __mempcpy ((char *) new_module->module_name,
directory, dir_len - 1);
*tmp++ = '/';
memcpy (tmp, module, wp - module);
}
if (__tfind (new_module, *modules, module_compare) != NULL)
tmp = __mempcpy (tmp, module, wp - module);
if (need_ext)
memcpy (tmp - 1, gconv_module_ext, sizeof (gconv_module_ext));
if (__tfind (new_module, modules, module_compare) == NULL)
if (__tsearch (new_module, modules, module_compare) == NULL)
/* Something went wrong while inserting the new module. */
free (new_module);
@ -267,7 +281,7 @@ static void
insert_module (const void *nodep, VISIT value, int level)
{
if (value == preorder || value == leaf)
__gconv_modules_db[__gconv_nmodules++] = (struct gconv_module *) nodep;
__gconv_modules_db[__gconv_nmodules++] = *(struct gconv_module **) nodep;
}
static void
@ -302,8 +316,6 @@ read_conf_file (const char *filename, const char *directory, size_t dir_len,
break;
rp = line;
while (isspace (*rp))
++rp;
/* Terminate the line (excluding comments or newline) by an NUL byte
to simplify the following code. */
endp = strchr (rp, '#');
@ -316,6 +328,9 @@ read_conf_file (const char *filename, const char *directory, size_t dir_len,
*endp = '\0';
}
while (isspace (*rp))
++rp;
/* If this is an empty line go on with the next one. */
if (rp == endp)
continue;
@ -325,10 +340,10 @@ read_conf_file (const char *filename, const char *directory, size_t dir_len,
++rp;
if (rp - word == sizeof ("alias") - 1
&& memcpy (word, "alias", sizeof ("alias") - 1) == 0)
&& memcmp (word, "alias", sizeof ("alias") - 1) == 0)
add_alias (rp);
else if (rp - word == sizeof ("module") - 1
&& memcpy (word, "module", sizeof ("module") - 1) == 0)
&& memcmp (word, "module", sizeof ("module") - 1) == 0)
add_module (rp, directory, dir_len, modules, nmodules);
/* else */
/* Otherwise ignore the line. */
@ -349,6 +364,7 @@ __gconv_read_conf (void)
char *gconv_path, *elem;
void *modules = NULL;
size_t nmodules = 0;
int save_errno = errno;
if (user_path == NULL)
/* No user-defined path. Make a modifiable copy of the default path. */
@ -390,31 +406,31 @@ __gconv_read_conf (void)
/* If the configuration files do not contain any valid module specification
remember this by setting the pointer to the module array to NULL. */
nmodules = sizeof (builtin_modules) / sizeof (struct gconv_module);
nmodules += sizeof (builtin_modules) / sizeof (builtin_modules[0]);
if (nmodules == 0)
__gconv_modules_db = NULL;
else
{
__gconv_modules_db = NULL;
return;
__gconv_modules_db =
(struct gconv_module **) malloc (nmodules
* sizeof (struct gconv_module));
if (__gconv_modules_db != NULL)
{
size_t cnt;
/* Insert all module entries into the array. */
__twalk (modules, insert_module);
/* No remove the tree data structure. */
__tdestroy (modules, nothing);
/* Finally insert the builtin transformations. */
for (cnt = 0; cnt < (sizeof (builtin_modules)
/ sizeof (struct gconv_module)); ++cnt)
__gconv_modules_db[__gconv_nmodules++] = &builtin_modules[cnt];
}
}
__gconv_modules_db =
(struct gconv_module **) malloc (nmodules * sizeof (struct gconv_module));
if (__gconv_modules_db == NULL)
/* We cannot do anything. */
return;
/* First insert the builtin transformations. */
while (__gconv_nmodules < (sizeof (builtin_modules)
/ sizeof (struct gconv_module)))
{
__gconv_modules_db[__gconv_nmodules] =
&builtin_modules[__gconv_nmodules];
++__gconv_nmodules;
}
/* Insert all module entries into the array. */
__twalk (modules, insert_module);
/* No remove the tree data structure. */
__tdestroy (modules, nothing);
/* Restore the error number. */
__set_errno (save_errno);
}

View file

@ -99,7 +99,7 @@ derivation_lookup (const char *fromset, const char *toset,
struct known_derivation key = { fromset, toset, NULL, 0 };
struct known_derivation *result;
result = __tfind (&key, known_derivations, derivation_compare);
result = __tfind (&key, &known_derivations, derivation_compare);
if (result == NULL)
return GCONV_NOCONV;
@ -169,11 +169,18 @@ gen_steps (struct derivation_step *best, const char *toset,
* step_cnt);
if (result != NULL)
{
int failed = 0;
*nsteps = step_cnt;
current = best;
while (step_cnt-- > 0)
{
result[step_cnt].from_name = current->last->result_set;
result[step_cnt].to_name = current->result_set;
result[step_cnt].from_name = (step_cnt == 0
? __strdup (fromset)
: current->last->result_set);
result[step_cnt].to_name = (step_cnt + 1 == *nsteps
? __strdup (current->result_set)
: result[step_cnt + 1].from_name);
if (current->code->module_name[0] == '/')
{
@ -182,7 +189,10 @@ gen_steps (struct derivation_step *best, const char *toset,
__gconv_find_shlib (current->code->module_name);
if (shlib_handle == NULL)
break;
{
failed = 1;
break;
}
result[step_cnt].shlib_handle = shlib_handle;
@ -192,6 +202,7 @@ gen_steps (struct derivation_step *best, const char *toset,
/* Argh, no conversion function. There is something
wrong here. */
__gconv_release_shlib (result[step_cnt].shlib_handle);
failed = 1;
break;
}
@ -208,18 +219,18 @@ gen_steps (struct derivation_step *best, const char *toset,
current = current->last;
}
if (step_cnt != 0)
if (failed != 0)
{
/* Something went wrong while initializing the modules. */
while (step_cnt-- > 0)
while (++step_cnt < *nsteps)
__gconv_release_shlib (result[step_cnt].shlib_handle);
free (result);
*nsteps = 0;
status = GCONV_NOCONV;
}
else
{
*handle = result;
*nsteps = step_cnt;
status = GCONV_OK;
}
}
@ -231,12 +242,13 @@ gen_steps (struct derivation_step *best, const char *toset,
/* The main function: find a possible derivation from the `fromset' (either
the given name or the alias) to the `toset' (again with alias). */
static int
internal_function
find_derivation (const char *toset, const char *toset_expand,
const char *fromset, const char *fromset_expand,
struct gconv_step **handle, size_t *nsteps)
{
__libc_lock_define_initialized (static, lock)
struct derivation_step *current, **lastp, *best = NULL;
struct derivation_step *first, *current, **lastp, *best = NULL;
int best_cost = 0;
int result;
@ -260,16 +272,17 @@ find_derivation (const char *toset, const char *toset_expand,
The task is to match the `toset' with any of the available. */
if (fromset_expand != NULL)
{
current = NEW_STEP (fromset_expand, NULL, NULL);
current->next = NEW_STEP (fromset, NULL, NULL);
lastp = &current->next->next;
first = NEW_STEP (fromset_expand, NULL, NULL);
first->next = NEW_STEP (fromset, NULL, NULL);
lastp = &first->next->next;
}
else
{
current = NEW_STEP (fromset, NULL, NULL);
lastp = &current->next;
first = NEW_STEP (fromset, NULL, NULL);
lastp = &first->next;
}
current = first;
while (current != NULL)
{
/* Now match all the available module specifications against the
@ -419,13 +432,28 @@ find_derivation (const char *toset, const char *toset_expand,
}
else
{
/* Append at the end. */
*lastp = NEW_STEP (result_set, __gconv_modules_db[cnt],
current);
lastp = &(*lastp)->next;
/* Append at the end if there is no entry with this name. */
struct derivation_step *runp = first;
while (runp != NULL)
{
if (__strcasecmp (result_set, runp->result_set) == 0)
break;
runp = runp->next;
}
if (runp == NULL)
{
*lastp = NEW_STEP (result_set, __gconv_modules_db[cnt],
current);
lastp = &(*lastp)->next;
}
}
}
}
/* Go on with the next entry. */
current = current->next;
}
if (best != NULL)
@ -470,15 +498,15 @@ __gconv_find_transform (const char *toset, const char *fromset,
if (__gconv_alias_db != NULL)
{
struct gconv_alias key;
struct gconv_alias *found;
struct gconv_alias **found;
key.fromname = fromset;
found = __tfind (&key, __gconv_alias_db, __gconv_alias_compare);
fromset_expand = found != NULL ? found->toname : NULL;
found = __tfind (&key, &__gconv_alias_db, __gconv_alias_compare);
fromset_expand = found != NULL ? (*found)->toname : NULL;
key.fromname = toset;
found = __tfind (&key, __gconv_alias_db, __gconv_alias_compare);
toset_expand = found != NULL ? found->toname : NULL;
found = __tfind (&key, &__gconv_alias_db, __gconv_alias_compare);
toset_expand = found != NULL ? (*found)->toname : NULL;
}
result = find_derivation (toset, toset_expand, fromset, fromset_expand,

View file

@ -84,6 +84,7 @@ do_open (void *a)
static int
internal_function
dlerror_run (void (*operate) (void *), void *args)
{
char *last_errstring = NULL;
@ -156,7 +157,7 @@ __gconv_find_shlib (const char *name)
enough to a pointer to our structure to use as a lookup key that
will be passed to `known_compare' (above). */
found = __tfind (&name, loaded, known_compare);
found = __tfind (&name, &loaded, known_compare);
if (found == NULL)
{
/* This name was not known before. */
@ -208,7 +209,7 @@ static void *release_handle;
static void
do_release_shlib (const void *nodep, VISIT value, int level)
{
struct loaded_object *obj = (struct loaded_object *) nodep;
struct loaded_object *obj = *(struct loaded_object **) nodep;
if (value != preorder && value != leaf)
return;

View file

@ -69,19 +69,19 @@ __gconv_open (const char *toset, const char *fromset, gconv_t *handle)
if (res != GCONV_OK)
break;
}
else
if (!data[cnt].is_last)
{
data[cnt].outbufsize = GCONV_DEFAULT_BUFSIZE;
data[cnt].outbuf =
(char *) malloc (data[cnt].outbufsize);
if (data[cnt].outbuf == NULL)
{
res = GCONV_NOMEM;
break;
}
data[cnt].outbufavail = 0;
}
if (!data[cnt].is_last && data[cnt].outbuf == NULL)
{
data[cnt].outbufsize = GCONV_DEFAULT_BUFSIZE;
data[cnt].outbuf =
(char *) malloc (data[cnt].outbufsize);
if (data[cnt].outbuf == NULL)
{
res = GCONV_NOMEM;
break;
}
data[cnt].outbufavail = 0;
}
}
}
}

View file

@ -117,7 +117,7 @@ __gconv_transform_ucs4_utf8 (struct gconv_step *step,
do
{
const char *newinbuf = inbuf;
size_t actually = __wcsnrtombs (&data->outbuf[data->outbufavail],
size_t actually = __wmemrtombs (&data->outbuf[data->outbufavail],
(const wchar_t **) &newinbuf,
*inlen / sizeof (wchar_t),
data->outbufsize - data->outbufavail,
@ -206,7 +206,7 @@ __gconv_transform_utf8_ucs4 (struct gconv_step *step,
do
{
const char *newinbuf = inbuf;
size_t actually = __mbsnrtowcs ((wchar_t *) &data->outbuf[data->outbufavail],
size_t actually = __wmemrtowcs ((wchar_t *) &data->outbuf[data->outbufavail],
&newinbuf, *inlen,
((data->outbufsize
- data->outbufavail)

View file

@ -19,9 +19,12 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <errno.h>
#include <iconv.h>
#include <gconv.h>
#include <assert.h>
size_t
iconv (iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf,
@ -29,10 +32,39 @@ iconv (iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf,
{
gconv_t gcd = (gconv_t) cd;
size_t converted;
int result;
if (__gconv (gcd, inbuf, inbytesleft, outbuf, outbytesleft, &converted)
!= GCONV_OK)
return (size_t) -1;
result = __gconv (gcd, inbuf, inbytesleft, outbuf, outbytesleft, &converted);
switch (result)
{
case GCONV_ILLEGAL_DESCRIPTOR:
__set_errno (EBADF);
converted = (size_t) -1L;
break;
case GCONV_ILLEGAL_INPUT:
__set_errno (EILSEQ);
converted = (size_t) -1L;
break;
case GCONV_FULL_OUTPUT:
__set_errno (E2BIG);
converted = (size_t) -1L;
break;
case GCONV_INCOMPLETE_INPUT:
__set_errno (EINVAL);
converted = (size_t) -1L;
break;
case GCONV_EMPTY_INPUT:
case GCONV_OK:
/* Nothing. */
break;
default:
assert (!"Nothing like this should happen");
}
return converted;
}

View file

@ -18,6 +18,7 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <errno.h>
#include <iconv.h>
#include <gconv.h>
@ -26,5 +27,11 @@
int
iconv_close (iconv_t cd)
{
if (cd == (iconv_t *) -1L)
{
__set_errno (EBADF);
return -1;
}
return __gconv_close ((gconv_t) cd) ? -1 : 0;
}

View file

@ -27,11 +27,9 @@
static inline void
strip (char *s)
strip (char *wp, const char *s)
{
int slash_count = 0;
char *wp;
wp = s;
while (*s != '\0')
{
@ -39,7 +37,7 @@ strip (char *s)
*wp++ = *s;
else if (*s == '/')
{
if (++slash_count == 2)
if (++slash_count == 3)
break;
*wp++ = '/';
}
@ -67,14 +65,15 @@ iconv_open (const char *tocode, const char *fromcode)
'_', '-', '/', and '.'. */
tocode_len = strlen (tocode);
tocode_conv = alloca (tocode_len + 3);
strip (memcpy (tocode_conv, tocode, tocode_len + 1));
strip (tocode_conv, tocode);
fromcode_len = strlen (fromcode);
fromcode_conv = alloca (fromcode_len + 3);
strip (memcpy (fromcode_conv, fromcode, fromcode_len + 1));
strip (fromcode_conv, fromcode);
res = __gconv_open (tocode_conv[2] == '\0' ? tocode : tocode_conv,
fromcode_conv[2] == '\0' ? fromcode, fromcode_conv, &cd);
fromcode_conv[2] == '\0' ? fromcode : fromcode_conv,
&cd);
if (res != GCONV_OK)
{

View file

@ -26,9 +26,8 @@
/* Safest assumption, if somehow the initializer isn't run. */
int __libc_enable_secure = 1;
static void
__attribute__ ((unused, constructor))
init_secure (void)
void
__libc_init_secure (void)
{
__libc_enable_secure = (__geteuid () != __getuid () ||
__getegid () != __getgid ());

View file

@ -29,7 +29,7 @@ routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \
wmemcmp wmemcpy wmemmove wmemset wcpcpy wcpncpy \
btowc wctob mbsinit \
mbrlen mbrtowc wcrtomb mbsrtowcs wcsrtombs \
mbsnrtowcs wcsnrtombs \
mbsnrtowcs wcsnrtombs wmemrtowcs wmemrtombs \
wcstol wcstoul wcstoll wcstoull wcstod wcstold wcstof \
wcstol_l wcstoul_l wcstoll_l wcstoull_l \
wcstod_l wcstold_l wcstof_l \

View file

@ -253,6 +253,16 @@ extern size_t mbsnrtowcs __P ((wchar_t *__restrict __dst,
__const char **__restrict __src, size_t __nmc,
size_t __len, mbstate_t *__restrict __ps));
/* Similar function to the above but this does not stop at NUL bytes. */
extern size_t __wmemrtowcs __P ((wchar_t *__restrict __dst,
__const char **__restrict __src,
size_t __nmc, size_t __len,
mbstate_t *__restrict __ps));
extern size_t wmemrtowcs __P ((wchar_t *__restrict __dst,
__const char **__restrict __src,
size_t __nmc, size_t __len,
mbstate_t *__restrict __ps));
/* Write multibyte character representation of at most NWC characters
from the wide character string SRC to DST. */
extern size_t __wcsnrtombs __P ((char *__restrict __dst,
@ -264,6 +274,16 @@ extern size_t wcsnrtombs __P ((char *__restrict __dst,
size_t __nwc, size_t __len,
mbstate_t *__restrict __ps));
/* Similar function to the above but this does not stop at NUL bytes. */
extern size_t __wmemrtombs __P ((char *__restrict __dst,
__const wchar_t **__restrict __src,
size_t __nwc, size_t len,
mbstate_t *__restrict __ps));
extern size_t wmemrtombs __P ((char *__restrict __dst,
__const wchar_t **__restrict __src,
size_t __nwc, size_t len,
mbstate_t *__restrict __ps));
/* The following functions are extensions found in X/Open CAE. */

121
wcsmbs/wmemrtombs.c Normal file
View file

@ -0,0 +1,121 @@
/* Copyright (C) 1997 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@gnu.org>, 1997.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <errno.h>
#include <wchar.h>
#ifndef EILSEQ
#define EILSEQ EINVAL
#endif
static const wchar_t encoding_mask[] =
{
~0x7ff, ~0xffff, ~0x1fffff, ~0x3ffffff
};
static const unsigned char encoding_byte[] =
{
0xc0, 0xe0, 0xf0, 0xf8, 0xfc
};
/* We don't need the state really because we don't have shift states
to maintain between calls to this function. */
static mbstate_t internal;
/* This is a non-standard function but it is very useful in the
implementation of stdio because we have to deal with unterminated
buffers. At most NWC wide character will be converted. */
size_t
__wmemrtombs (dst, src, nwc, len, ps)
char *dst;
const wchar_t **src;
size_t nwc;
size_t len;
mbstate_t *ps;
{
size_t written = 0;
const wchar_t *run = *src;
if (ps == NULL)
ps = &internal;
if (dst == NULL)
/* The LEN parameter has to be ignored if we don't actually write
anything. */
len = ~0;
while (written < len && nwc-- > 0)
{
wchar_t wc = *run++;
if (wc < 0 || wc > 0x7fffffff)
{
/* This is no correct ISO 10646 character. */
__set_errno (EILSEQ);
return (size_t) -1;
}
if (wc < 0x80)
{
/* It's an one byte sequence. */
if (dst != NULL)
*dst++ = (char) wc;
++written;
}
else
{
size_t step;
for (step = 2; step < 6; ++step)
if ((wc & encoding_mask[step - 2]) == 0)
break;
if (written + step >= len)
/* Too long. */
break;
if (dst != NULL)
{
size_t cnt = step;
dst[0] = encoding_byte[cnt - 2];
--cnt;
do
{
dst[cnt] = 0x80 | (wc & 0x3f);
wc >>= 6;
}
while (--cnt > 0);
dst[0] |= wc;
dst += step;
}
written += step;
}
}
/* Store position of first unprocessed word. */
*src = run;
return written;
}
weak_alias (__wmemrtombs, wmemrtombs)

134
wcsmbs/wmemrtowcs.c Normal file
View file

@ -0,0 +1,134 @@
/* Copyright (C) 1997 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@gnu.org>, 1997.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <errno.h>
#include <wchar.h>
#ifndef EILSEQ
#define EILSEQ EINVAL
#endif
/* We don't need the state really because we don't have shift states
to maintain between calls to this function. */
static mbstate_t internal;
/* This is a non-standard function but it is very useful in the
implementation of stdio because we have to deal with unterminated
buffers. At most NMC bytes will be converted. */
size_t
__wmemrtowcs (dst, src, nmc, len, ps)
wchar_t *dst;
const char **src;
size_t nmc;
size_t len;
mbstate_t *ps;
{
size_t written = 0;
const char *run = *src;
const char *last = run + nmc;
if (ps == NULL)
ps = &internal;
if (dst == NULL)
/* The LEN parameter has to be ignored if we don't actually write
anything. */
len = ~0;
/* Copy all words. */
while (written < len && run < last)
{
wchar_t value;
size_t count;
unsigned char byte = *run++;
/* We expect a start of a new multibyte character. */
if (byte < 0x80)
{
/* One byte sequence. */
count = 0;
value = byte;
}
else if ((byte & 0xe0) == 0xc0)
{
count = 1;
value = byte & 0x1f;
}
else if ((byte & 0xf0) == 0xe0)
{
/* We expect three bytes. */
count = 2;
value = byte & 0x0f;
}
else if ((byte & 0xf8) == 0xf0)
{
/* We expect four bytes. */
count = 3;
value = byte & 0x07;
}
else if ((byte & 0xfc) == 0xf8)
{
/* We expect five bytes. */
count = 4;
value = byte & 0x03;
}
else if ((byte & 0xfe) == 0xfc)
{
/* We expect six bytes. */
count = 5;
value = byte & 0x01;
}
else
{
/* This is an illegal encoding. */
__set_errno (EILSEQ);
return (size_t) -1;
}
/* Read the possible remaining bytes. */
while (count-- > 0)
{
byte = *run++;
if ((byte & 0xc0) != 0x80)
{
/* This is an illegal encoding. */
__set_errno (EILSEQ);
return (size_t) -1;
}
value <<= 6;
value |= byte & 0x3f;
}
/* Store value is required. */
if (dst != NULL)
*dst++ = value;
/* Increment counter of produced words. */
++written;
}
/* Store address of next byte to process. */
*src = run;
return written;
}
weak_alias (__wmemrtowcs, wmemrtowcs)