1946379e7Schristos /* Determine the Java version supported by javaexec.
2946379e7Schristos Copyright (C) 2006 Free Software Foundation, Inc.
3946379e7Schristos Written by Bruno Haible <bruno@clisp.org>, 2006.
4946379e7Schristos
5946379e7Schristos This program is free software; you can redistribute it and/or modify
6946379e7Schristos it under the terms of the GNU General Public License as published by
7946379e7Schristos the Free Software Foundation; either version 2, or (at your option)
8946379e7Schristos any later version.
9946379e7Schristos
10946379e7Schristos This program is distributed in the hope that it will be useful,
11946379e7Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of
12946379e7Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13946379e7Schristos GNU General Public License for more details.
14946379e7Schristos
15946379e7Schristos You should have received a copy of the GNU General Public License
16946379e7Schristos along with this program; if not, write to the Free Software Foundation,
17946379e7Schristos Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
18946379e7Schristos
19946379e7Schristos #include <config.h>
20946379e7Schristos
21946379e7Schristos /* Specification. */
22946379e7Schristos #include "javaversion.h"
23946379e7Schristos
24946379e7Schristos #include <errno.h>
25946379e7Schristos #include <stdbool.h>
26946379e7Schristos #include <stdio.h>
27946379e7Schristos
28946379e7Schristos #if ENABLE_RELOCATABLE
29946379e7Schristos # include "relocatable.h"
30946379e7Schristos #else
31946379e7Schristos # define relocate(pathname) (pathname)
32946379e7Schristos #endif
33946379e7Schristos
34946379e7Schristos /* Get PKGDATADIR. */
35*95b39c65Schristos #ifndef PKGDATADIR
36946379e7Schristos #include "configmake.h"
37*95b39c65Schristos #endif
38946379e7Schristos
39946379e7Schristos #include "javaexec.h"
40946379e7Schristos #include "pipe.h"
41946379e7Schristos #include "wait-process.h"
42946379e7Schristos #include "error.h"
43946379e7Schristos #include "getline.h"
44946379e7Schristos #include "gettext.h"
45946379e7Schristos
46946379e7Schristos #define _(str) gettext (str)
47946379e7Schristos
48946379e7Schristos
49946379e7Schristos struct locals
50946379e7Schristos {
51946379e7Schristos /* OUT */
52946379e7Schristos char *line;
53946379e7Schristos };
54946379e7Schristos
55946379e7Schristos static bool
execute_and_read_line(const char * progname,const char * prog_path,char ** prog_argv,void * private_data)56946379e7Schristos execute_and_read_line (const char *progname,
57946379e7Schristos const char *prog_path, char **prog_argv,
58946379e7Schristos void *private_data)
59946379e7Schristos {
60946379e7Schristos struct locals *l = (struct locals *) private_data;
61946379e7Schristos pid_t child;
62946379e7Schristos int fd[1];
63946379e7Schristos FILE *fp;
64946379e7Schristos char *line;
65946379e7Schristos size_t linesize;
66946379e7Schristos size_t linelen;
67946379e7Schristos int exitstatus;
68946379e7Schristos
69946379e7Schristos /* Open a pipe to the JVM. */
70946379e7Schristos child = create_pipe_in (progname, prog_path, prog_argv, DEV_NULL, false,
71946379e7Schristos true, false, fd);
72946379e7Schristos
73946379e7Schristos if (child == -1)
74946379e7Schristos return false;
75946379e7Schristos
76946379e7Schristos /* Retrieve its result. */
77946379e7Schristos fp = fdopen (fd[0], "r");
78946379e7Schristos if (fp == NULL)
79946379e7Schristos {
80946379e7Schristos error (0, errno, _("fdopen() failed"));
81946379e7Schristos return false;
82946379e7Schristos }
83946379e7Schristos
84946379e7Schristos line = NULL; linesize = 0;
85946379e7Schristos linelen = getline (&line, &linesize, fp);
86946379e7Schristos if (linelen == (size_t)(-1))
87946379e7Schristos {
88946379e7Schristos error (0, 0, _("%s subprocess I/O error"), progname);
89946379e7Schristos return false;
90946379e7Schristos }
91946379e7Schristos if (linelen > 0 && line[linelen - 1] == '\n')
92946379e7Schristos line[linelen - 1] = '\0';
93946379e7Schristos
94946379e7Schristos fclose (fp);
95946379e7Schristos
96946379e7Schristos /* Remove zombie process from process list, and retrieve exit status. */
97946379e7Schristos exitstatus = wait_subprocess (child, progname, true, false, true, false);
98946379e7Schristos if (exitstatus != 0)
99946379e7Schristos {
100946379e7Schristos free (line);
101946379e7Schristos return false;
102946379e7Schristos }
103946379e7Schristos
104946379e7Schristos l->line = line;
105946379e7Schristos return false;
106946379e7Schristos }
107946379e7Schristos
108946379e7Schristos char *
javaexec_version(void)109946379e7Schristos javaexec_version (void)
110946379e7Schristos {
111946379e7Schristos const char *class_name = "javaversion";
112946379e7Schristos const char *pkgdatadir = relocate (PKGDATADIR);
113946379e7Schristos const char *args[1];
114946379e7Schristos struct locals locals;
115946379e7Schristos
116946379e7Schristos args[0] = NULL;
117946379e7Schristos locals.line = NULL;
118946379e7Schristos execute_java_class (class_name, &pkgdatadir, 1, true, NULL, args,
119946379e7Schristos false, false, execute_and_read_line, &locals);
120946379e7Schristos
121946379e7Schristos return locals.line;
122946379e7Schristos }
123