Add prototype.
[glibc.git] / iconvdata / tst-loading.c
blob8849ebdcd8891d0f9bf9d211b6e7a3108b0750e7
1 /* Tests for loading and unloading of iconv modules.
2 Copyright (C) 2000 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Contributed by Ulrich Drepper <drepper@cygnus.com>, 2000.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public License as
8 published by the Free Software Foundation; either version 2 of the
9 License, or (at your option) any later version.
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
16 You should have received a copy of the GNU Library General Public
17 License along with the GNU C Library; see the file COPYING.LIB. If not,
18 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
21 #include <iconv.h>
22 #include <mcheck.h>
23 #include <stdio.h>
24 #include <stdlib.h>
27 /* How many load/unload operations do we do. */
28 #define TEST_ROUNDS 5000
31 enum state { unloaded, loaded };
33 struct
35 const char *name;
36 enum state state;
37 iconv_t cd;
38 } modules[] =
40 #define MODULE(Name) { .name = #Name, .state = unloaded }
41 MODULE (ISO-8859-1),
42 MODULE (ISO-8859-2),
43 MODULE (ISO-8859-3),
44 MODULE (ISO-8859-4),
45 MODULE (ISO-8859-5),
46 MODULE (ISO-8859-6),
47 MODULE (ISO-8859-15),
48 MODULE (EUC-JP),
49 MODULE (EUC-KR),
50 MODULE (EUC-CN),
51 MODULE (EUC-TW),
52 MODULE (SJIS),
53 MODULE (UHC),
54 MODULE (KOI8-R),
55 MODULE (BIG5),
56 MODULE (BIG5HKSCS)
58 #define nmodules (sizeof (modules) / sizeof (modules[0]))
61 /* The test data. */
62 static const char inbuf[] = "\
63 The first step is the function to create a handle.
65 - Function: iconv_t iconv_open (const char *TOCODE, const char
66 *FROMCODE)
67 The `iconv_open' function has to be used before starting a
68 conversion. The two parameters this function takes determine the
69 source and destination character set for the conversion and if the
70 implementation has the possibility to perform such a conversion the
71 function returns a handle.
73 If the wanted conversion is not available the function returns
74 `(iconv_t) -1'. In this case the global variable `errno' can have
75 the following values:
77 `EMFILE'
78 The process already has `OPEN_MAX' file descriptors open.
80 `ENFILE'
81 The system limit of open file is reached.
83 `ENOMEM'
84 Not enough memory to carry out the operation.
86 `EINVAL'
87 The conversion from FROMCODE to TOCODE is not supported.
89 It is not possible to use the same descriptor in different threads
90 to perform independent conversions. Within the data structures
91 associated with the descriptor there is information about the
92 conversion state. This must not be messed up by using it in
93 different conversions.
95 An `iconv' descriptor is like a file descriptor as for every use a
96 new descriptor must be created. The descriptor does not stand for
97 all of the conversions from FROMSET to TOSET.
99 The GNU C library implementation of `iconv_open' has one
100 significant extension to other implementations. To ease the
101 extension of the set of available conversions the implementation
102 allows storing the necessary files with data and code in
103 arbitrarily many directories. How this extension has to be
104 written will be explained below (*note glibc iconv
105 Implementation::). Here it is only important to say that all
106 directories mentioned in the `GCONV_PATH' environment variable are
107 considered if they contain a file `gconv-modules'. These
108 directories need not necessarily be created by the system
109 administrator. In fact, this extension is introduced to help users
110 writing and using their own, new conversions. Of course this does
111 not work for security reasons in SUID binaries; in this case only
112 the system directory is considered and this normally is
113 `PREFIX/lib/gconv'. The `GCONV_PATH' environment variable is
114 examined exactly once at the first call of the `iconv_open'
115 function. Later modifications of the variable have no effect.
120 main (void)
122 int count = TEST_ROUNDS;
123 int result = 0;
125 mtrace ();
127 /* Just a seed. */
128 srandom (TEST_ROUNDS);
130 while (count--)
132 int idx = random () % nmodules;
134 if (modules[idx].state == unloaded)
136 char outbuf[10000];
137 char *inptr = (char *) inbuf;
138 size_t insize = sizeof (inbuf) - 1;
139 char *outptr = outbuf;
140 size_t outsize = sizeof (outbuf);
142 /* Load the module and do the conversion. */
143 modules[idx].cd = iconv_open ("UTF-8", modules[idx].name);
145 if (modules[idx].cd == (iconv_t) -1)
147 printf ("opening of %s failed: %m\n", modules[idx].name);
148 result = 1;
149 break;
152 modules[idx].state = loaded;
154 /* Now a simple test. */
155 if (iconv (modules[idx].cd, &inptr, &insize, &outptr, &outsize) != 0
156 || *inptr != '\0')
158 printf ("conversion with %s failed\n", modules[idx].name);
159 result = 1;
162 else
164 /* Unload the module. */
165 if (iconv_close (modules[idx].cd) != 0)
167 printf ("closing of %s failed: %m\n", modules[idx].name);
168 result = 1;
169 break;
172 modules[idx].state = unloaded;
176 for (count = 0; count < nmodules; ++count)
177 if (modules[count].state == loaded && iconv_close (modules[count].cd) != 0)
179 printf ("closing of %s failed: %m\n", modules[count].name);
180 result = 1;
183 return result;