1 /* Determine the Java version supported by javaexec.
2 Copyright (C) 2006 Free Software Foundation, Inc.
3 Written by Bruno Haible <bruno@clisp.org>, 2006.
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 2, or (at your option)
8 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, write to the Free Software Foundation,
17 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
18
19 #include <config.h>
20
21 /* Specification. */
22 #include "javaversion.h"
23
24 #include <errno.h>
25 #include <stdbool.h>
26 #include <stdio.h>
27
28 #if ENABLE_RELOCATABLE
29 # include "relocatable.h"
30 #else
31 # define relocate(pathname) (pathname)
32 #endif
33
34 /* Get PKGDATADIR. */
35 #ifndef PKGDATADIR
36 #include "configmake.h"
37 #endif
38
39 #include "javaexec.h"
40 #include "pipe.h"
41 #include "wait-process.h"
42 #include "error.h"
43 #include "getline.h"
44 #include "gettext.h"
45
46 #define _(str) gettext (str)
47
48
49 struct locals
50 {
51 /* OUT */
52 char *line;
53 };
54
55 static bool
execute_and_read_line(const char * progname,const char * prog_path,char ** prog_argv,void * private_data)56 execute_and_read_line (const char *progname,
57 const char *prog_path, char **prog_argv,
58 void *private_data)
59 {
60 struct locals *l = (struct locals *) private_data;
61 pid_t child;
62 int fd[1];
63 FILE *fp;
64 char *line;
65 size_t linesize;
66 size_t linelen;
67 int exitstatus;
68
69 /* Open a pipe to the JVM. */
70 child = create_pipe_in (progname, prog_path, prog_argv, DEV_NULL, false,
71 true, false, fd);
72
73 if (child == -1)
74 return false;
75
76 /* Retrieve its result. */
77 fp = fdopen (fd[0], "r");
78 if (fp == NULL)
79 {
80 error (0, errno, _("fdopen() failed"));
81 return false;
82 }
83
84 line = NULL; linesize = 0;
85 linelen = getline (&line, &linesize, fp);
86 if (linelen == (size_t)(-1))
87 {
88 error (0, 0, _("%s subprocess I/O error"), progname);
89 return false;
90 }
91 if (linelen > 0 && line[linelen - 1] == '\n')
92 line[linelen - 1] = '\0';
93
94 fclose (fp);
95
96 /* Remove zombie process from process list, and retrieve exit status. */
97 exitstatus = wait_subprocess (child, progname, true, false, true, false);
98 if (exitstatus != 0)
99 {
100 free (line);
101 return false;
102 }
103
104 l->line = line;
105 return false;
106 }
107
108 char *
javaexec_version(void)109 javaexec_version (void)
110 {
111 const char *class_name = "javaversion";
112 const char *pkgdatadir = relocate (PKGDATADIR);
113 const char *args[1];
114 struct locals locals;
115
116 args[0] = NULL;
117 locals.line = NULL;
118 execute_java_class (class_name, &pkgdatadir, 1, true, NULL, args,
119 false, false, execute_and_read_line, &locals);
120
121 return locals.line;
122 }
123