• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-WNDR4500v2-V1.0.0.60_1.0.38/ap/gpl/timemachine/gettext-0.17/gettext-tools/gnulib-lib/
1/* Execute a Java program.
2   Copyright (C) 2001-2003, 2006-2007 Free Software Foundation, Inc.
3   Written by Bruno Haible <haible@clisp.cons.org>, 2001.
4
5   This program is free software: you can redistribute it and/or modify
6   it under the terms of the GNU General Public License as published by
7   the Free Software Foundation; either version 3 of the License, or
8   (at your option) any later version.
9
10   This program is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   GNU General Public License for more details.
14
15   You should have received a copy of the GNU General Public License
16   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
17
18#include <config.h>
19#include <alloca.h>
20
21/* Specification.  */
22#include "javaexec.h"
23
24#include <stdio.h>
25#include <stdlib.h>
26#include <string.h>
27
28#include "execute.h"
29#include "classpath.h"
30#include "xsetenv.h"
31#include "sh-quote.h"
32#include "filename.h"
33#include "xalloc.h"
34#include "xmalloca.h"
35#include "error.h"
36#include "gettext.h"
37
38#define _(str) gettext (str)
39
40
41/* Survey of Java virtual machines.
42
43   A = does it work without CLASSPATH being set
44   B = does it work with CLASSPATH being set to empty
45   C = option to set CLASSPATH, other than setting it in the environment
46   T = test for presence
47
48   Program    from         A B  C              T
49
50   $JAVA      unknown      N Y  n/a            true
51   gij        GCC 3.0      Y Y  n/a            gij --version >/dev/null
52   java       JDK 1.1.8    Y Y  -classpath P   java -version 2>/dev/null
53   jre        JDK 1.1.8    N Y  -classpath P   jre 2>/dev/null; test $? = 1
54   java       JDK 1.3.0    Y Y  -classpath P   java -version 2>/dev/null
55   jview      MS IE        Y Y  -cp P          jview -? >nul; %errorlevel% = 1
56
57   The CLASSPATH is a colon separated list of pathnames. (On Windows: a
58   semicolon separated list of pathnames.)
59
60   We try the Java virtual machines in the following order:
61     1. getenv ("JAVA"), because the user must be able to override our
62	preferences,
63     2. "gij", because it is a completely free JVM,
64     3. "java", because it is a standard JVM,
65     4. "jre", comes last because it requires a CLASSPATH environment variable,
66     5. "jview", on Windows only, because it is frequently installed.
67
68   We unset the JAVA_HOME environment variable, because a wrong setting of
69   this variable can confuse the JDK's javac.
70 */
71
72bool
73execute_java_class (const char *class_name,
74		    const char * const *classpaths,
75		    unsigned int classpaths_count,
76		    bool use_minimal_classpath,
77		    const char *exe_dir,
78		    const char * const *args,
79		    bool verbose, bool quiet,
80		    execute_fn *executer, void *private_data)
81{
82  bool err = false;
83  unsigned int nargs;
84  char *old_JAVA_HOME;
85
86  /* Count args.  */
87  {
88    const char * const *arg;
89
90    for (nargs = 0, arg = args; *arg != NULL; nargs++, arg++)
91     ;
92  }
93
94  /* First, try a class compiled to a native code executable.  */
95  if (exe_dir != NULL)
96    {
97      char *exe_pathname = concatenated_filename (exe_dir, class_name, EXEEXT);
98      char *old_classpath;
99      char **argv = (char **) xmalloca ((1 + nargs + 1) * sizeof (char *));
100      unsigned int i;
101
102      /* Set CLASSPATH.  */
103      old_classpath =
104	set_classpath (classpaths, classpaths_count, use_minimal_classpath,
105		       verbose);
106
107      argv[0] = exe_pathname;
108      for (i = 0; i <= nargs; i++)
109	argv[1 + i] = (char *) args[i];
110
111      if (verbose)
112	{
113	  char *command = shell_quote_argv (argv);
114	  printf ("%s\n", command);
115	  free (command);
116	}
117
118      err = executer (class_name, exe_pathname, argv, private_data);
119
120      /* Reset CLASSPATH.  */
121      reset_classpath (old_classpath);
122
123      freea (argv);
124
125      goto done1;
126    }
127
128  {
129    const char *java = getenv ("JAVA");
130    if (java != NULL && java[0] != '\0')
131      {
132	/* Because $JAVA may consist of a command and options, we use the
133	   shell.  Because $JAVA has been set by the user, we leave all
134	   all environment variables in place, including JAVA_HOME, and
135	   we don't erase the user's CLASSPATH.  */
136	char *old_classpath;
137	unsigned int command_length;
138	char *command;
139	char *argv[4];
140	const char * const *arg;
141	char *p;
142
143	/* Set CLASSPATH.  */
144	old_classpath =
145	  set_classpath (classpaths, classpaths_count, false,
146			 verbose);
147
148	command_length = strlen (java);
149	command_length += 1 + shell_quote_length (class_name);
150	for (arg = args; *arg != NULL; arg++)
151	  command_length += 1 + shell_quote_length (*arg);
152	command_length += 1;
153
154	command = (char *) xmalloca (command_length);
155	p = command;
156	/* Don't shell_quote $JAVA, because it may consist of a command
157	   and options.  */
158	memcpy (p, java, strlen (java));
159	p += strlen (java);
160	*p++ = ' ';
161	p = shell_quote_copy (p, class_name);
162	for (arg = args; *arg != NULL; arg++)
163	  {
164	    *p++ = ' ';
165	    p = shell_quote_copy (p, *arg);
166	  }
167	*p++ = '\0';
168	/* Ensure command_length was correctly calculated.  */
169	if (p - command > command_length)
170	  abort ();
171
172	if (verbose)
173	  printf ("%s\n", command);
174
175	argv[0] = "/bin/sh";
176	argv[1] = "-c";
177	argv[2] = command;
178	argv[3] = NULL;
179	err = executer (java, "/bin/sh", argv, private_data);
180
181	freea (command);
182
183	/* Reset CLASSPATH.  */
184	reset_classpath (old_classpath);
185
186	goto done1;
187      }
188  }
189
190  /* Unset the JAVA_HOME environment variable.  */
191  old_JAVA_HOME = getenv ("JAVA_HOME");
192  if (old_JAVA_HOME != NULL)
193    {
194      old_JAVA_HOME = xstrdup (old_JAVA_HOME);
195      unsetenv ("JAVA_HOME");
196    }
197
198  {
199    static bool gij_tested;
200    static bool gij_present;
201
202    if (!gij_tested)
203      {
204	/* Test for presence of gij: "gij --version > /dev/null"  */
205	char *argv[3];
206	int exitstatus;
207
208	argv[0] = "gij";
209	argv[1] = "--version";
210	argv[2] = NULL;
211	exitstatus = execute ("gij", "gij", argv, false, false, true, true,
212			      true, false);
213	gij_present = (exitstatus == 0);
214	gij_tested = true;
215      }
216
217    if (gij_present)
218      {
219	char *old_classpath;
220	char **argv = (char **) xmalloca ((2 + nargs + 1) * sizeof (char *));
221	unsigned int i;
222
223	/* Set CLASSPATH.  */
224	old_classpath =
225	  set_classpath (classpaths, classpaths_count, use_minimal_classpath,
226			 verbose);
227
228	argv[0] = "gij";
229	argv[1] = (char *) class_name;
230	for (i = 0; i <= nargs; i++)
231	  argv[2 + i] = (char *) args[i];
232
233	if (verbose)
234	  {
235	    char *command = shell_quote_argv (argv);
236	    printf ("%s\n", command);
237	    free (command);
238	  }
239
240	err = executer ("gij", "gij", argv, private_data);
241
242	/* Reset CLASSPATH.  */
243	reset_classpath (old_classpath);
244
245	freea (argv);
246
247	goto done2;
248      }
249  }
250
251  {
252    static bool java_tested;
253    static bool java_present;
254
255    if (!java_tested)
256      {
257	/* Test for presence of java: "java -version 2> /dev/null"  */
258	char *argv[3];
259	int exitstatus;
260
261	argv[0] = "java";
262	argv[1] = "-version";
263	argv[2] = NULL;
264	exitstatus = execute ("java", "java", argv, false, false, true, true,
265			      true, false);
266	java_present = (exitstatus == 0);
267	java_tested = true;
268      }
269
270    if (java_present)
271      {
272	char *old_classpath;
273	char **argv = (char **) xmalloca ((2 + nargs + 1) * sizeof (char *));
274	unsigned int i;
275
276	/* Set CLASSPATH.  We don't use the "-classpath ..." option because
277	   in JDK 1.1.x its argument should also contain the JDK's classes.zip,
278	   but we don't know its location.  (In JDK 1.3.0 it would work.)  */
279	old_classpath =
280	  set_classpath (classpaths, classpaths_count, use_minimal_classpath,
281			 verbose);
282
283	argv[0] = "java";
284	argv[1] = (char *) class_name;
285	for (i = 0; i <= nargs; i++)
286	  argv[2 + i] = (char *) args[i];
287
288	if (verbose)
289	  {
290	    char *command = shell_quote_argv (argv);
291	    printf ("%s\n", command);
292	    free (command);
293	  }
294
295	err = executer ("java", "java", argv, private_data);
296
297	/* Reset CLASSPATH.  */
298	reset_classpath (old_classpath);
299
300	freea (argv);
301
302	goto done2;
303      }
304  }
305
306  {
307    static bool jre_tested;
308    static bool jre_present;
309
310    if (!jre_tested)
311      {
312	/* Test for presence of jre: "jre 2> /dev/null ; test $? = 1"  */
313	char *argv[2];
314	int exitstatus;
315
316	argv[0] = "jre";
317	argv[1] = NULL;
318	exitstatus = execute ("jre", "jre", argv, false, false, true, true,
319			      true, false);
320	jre_present = (exitstatus == 0 || exitstatus == 1);
321	jre_tested = true;
322      }
323
324    if (jre_present)
325      {
326	char *old_classpath;
327	char **argv = (char **) xmalloca ((2 + nargs + 1) * sizeof (char *));
328	unsigned int i;
329
330	/* Set CLASSPATH.  We don't use the "-classpath ..." option because
331	   in JDK 1.1.x its argument should also contain the JDK's classes.zip,
332	   but we don't know its location.  */
333	old_classpath =
334	  set_classpath (classpaths, classpaths_count, use_minimal_classpath,
335			 verbose);
336
337	argv[0] = "jre";
338	argv[1] = (char *) class_name;
339	for (i = 0; i <= nargs; i++)
340	  argv[2 + i] = (char *) args[i];
341
342	if (verbose)
343	  {
344	    char *command = shell_quote_argv (argv);
345	    printf ("%s\n", command);
346	    free (command);
347	  }
348
349	err = executer ("jre", "jre", argv, private_data);
350
351	/* Reset CLASSPATH.  */
352	reset_classpath (old_classpath);
353
354	freea (argv);
355
356	goto done2;
357      }
358  }
359
360#if defined _WIN32 || defined __WIN32__ || defined __CYGWIN__
361  /* Win32, Cygwin */
362  {
363    static bool jview_tested;
364    static bool jview_present;
365
366    if (!jview_tested)
367      {
368	/* Test for presence of jview: "jview -? >nul ; test $? = 1"  */
369	char *argv[3];
370	int exitstatus;
371
372	argv[0] = "jview";
373	argv[1] = "-?";
374	argv[2] = NULL;
375	exitstatus = execute ("jview", "jview", argv, false, false, true, true,
376			      true, false);
377	jview_present = (exitstatus == 0 || exitstatus == 1);
378	jview_tested = true;
379      }
380
381    if (jview_present)
382      {
383	char *old_classpath;
384	char **argv = (char **) xmalloca ((2 + nargs + 1) * sizeof (char *));
385	unsigned int i;
386
387	/* Set CLASSPATH.  */
388	old_classpath =
389	  set_classpath (classpaths, classpaths_count, use_minimal_classpath,
390			 verbose);
391
392	argv[0] = "jview";
393	argv[1] = (char *) class_name;
394	for (i = 0; i <= nargs; i++)
395	  argv[2 + i] = (char *) args[i];
396
397	if (verbose)
398	  {
399	    char *command = shell_quote_argv (argv);
400	    printf ("%s\n", command);
401	    free (command);
402	  }
403
404	err = executer ("jview", "jview", argv, private_data);
405
406	/* Reset CLASSPATH.  */
407	reset_classpath (old_classpath);
408
409	freea (argv);
410
411	goto done2;
412      }
413  }
414#endif
415
416  if (!quiet)
417    error (0, 0, _("Java virtual machine not found, try installing gij or set $JAVA"));
418  err = true;
419
420 done2:
421  if (old_JAVA_HOME != NULL)
422    {
423      xsetenv ("JAVA_HOME", old_JAVA_HOME, 1);
424      free (old_JAVA_HOME);
425    }
426
427 done1:
428  return err;
429}
430