]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgfortran/intrinsics/execute_command_line.c
Update copyright years.
[thirdparty/gcc.git] / libgfortran / intrinsics / execute_command_line.c
CommitLineData
c14c8155 1/* Implementation of the EXECUTE_COMMAND_LINE intrinsic.
5624e564 2 Copyright (C) 2009-2015 Free Software Foundation, Inc.
c14c8155
FXC
3 Contributed by François-Xavier Coudert.
4
5This file is part of the GNU Fortran runtime library (libgfortran).
6
7Libgfortran is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 3, or (at your option) any later
10version.
11
12Libgfortran is distributed in the hope that it will be useful, but WITHOUT
13ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
16
17Under Section 7 of GPL version 3, you are granted additional
18permissions described in the GCC Runtime Library Exception, version
193.1, as published by the Free Software Foundation.
20
21You should have received a copy of the GNU General Public License and
22a copy of the GCC Runtime Library Exception along with this program;
23see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24<http://www.gnu.org/licenses/>. */
25
26#include "libgfortran.h"
27#include <string.h>
c14c8155 28#include <stdlib.h>
74544378 29
c14c8155
FXC
30#ifdef HAVE_UNISTD_H
31#include <unistd.h>
32#endif
33#ifdef HAVE_SYS_WAIT_H
34#include <sys/wait.h>
35#endif
36
37
b4224aec
TB
38enum { EXEC_SYNCHRONOUS = -2, EXEC_NOERROR = 0, EXEC_SYSTEMFAILED,
39 EXEC_CHILDFAILED };
c14c8155 40static const char *cmdmsg_values[] =
b4224aec
TB
41 { "",
42 "Termination status of the command-language interpreter cannot be obtained",
43 "Execution of child process impossible" };
c14c8155
FXC
44
45
46
47static void
48set_cmdstat (int *cmdstat, int value)
49{
50 if (cmdstat)
51 *cmdstat = value;
b4224aec 52 else if (value > EXEC_NOERROR)
c14c8155
FXC
53 runtime_error ("Could not execute command line");
54}
55
56
57static void
58execute_command_line (const char *command, bool wait, int *exitstat,
59 int *cmdstat, char *cmdmsg,
60 gfc_charlen_type command_len,
61 gfc_charlen_type cmdmsg_len)
62{
63 /* Transform the Fortran string to a C string. */
581d2326 64 char *cmd = fc_strdup (command, command_len);
c14c8155
FXC
65
66 /* Flush all I/O units before executing the command. */
67 flush_all_units();
68
69#if defined(HAVE_FORK)
70 if (!wait)
71 {
72 /* Asynchronous execution. */
73 pid_t pid;
74
b4224aec 75 set_cmdstat (cmdstat, EXEC_NOERROR);
c14c8155
FXC
76
77 if ((pid = fork()) < 0)
b4224aec 78 set_cmdstat (cmdstat, EXEC_CHILDFAILED);
c14c8155
FXC
79 else if (pid == 0)
80 {
81 /* Child process. */
82 int res = system (cmd);
83 _exit (WIFEXITED(res) ? WEXITSTATUS(res) : res);
84 }
85 }
86 else
87#endif
88 {
89 /* Synchronous execution. */
90 int res = system (cmd);
91
b4224aec 92 if (res == -1)
c14c8155 93 set_cmdstat (cmdstat, EXEC_SYSTEMFAILED);
43b594b4 94#ifndef HAVE_FORK
b4224aec
TB
95 else if (!wait)
96 set_cmdstat (cmdstat, EXEC_SYNCHRONOUS);
43b594b4 97#endif
c14c8155 98 else
b4224aec
TB
99 set_cmdstat (cmdstat, EXEC_NOERROR);
100
101 if (res != -1)
c14c8155 102 {
c14c8155
FXC
103#if defined(WEXITSTATUS) && defined(WIFEXITED)
104 *exitstat = WIFEXITED(res) ? WEXITSTATUS(res) : res;
105#else
106 *exitstat = res;
107#endif
108 }
109 }
110
581d2326
JB
111 free (cmd);
112
c14c8155 113 /* Now copy back to the Fortran string if needed. */
b4224aec 114 if (cmdstat && *cmdstat > EXEC_NOERROR)
c14c8155
FXC
115 {
116 if (cmdmsg)
117 fstrcpy (cmdmsg, cmdmsg_len, cmdmsg_values[*cmdstat],
118 strlen (cmdmsg_values[*cmdstat]));
119 else
120 runtime_error ("Failure in EXECUTE_COMMAND_LINE: %s",
121 cmdmsg_values[*cmdstat]);
122 }
123}
124
125
126extern void
127execute_command_line_i4 (const char *command, GFC_LOGICAL_4 *wait,
128 GFC_INTEGER_4 *exitstat, GFC_INTEGER_4 *cmdstat,
129 char *cmdmsg, gfc_charlen_type command_len,
130 gfc_charlen_type cmdmsg_len);
131export_proto(execute_command_line_i4);
132
133void
134execute_command_line_i4 (const char *command, GFC_LOGICAL_4 *wait,
135 GFC_INTEGER_4 *exitstat, GFC_INTEGER_4 *cmdstat,
136 char *cmdmsg, gfc_charlen_type command_len,
137 gfc_charlen_type cmdmsg_len)
138{
139 bool w = wait ? *wait : true;
140 int estat, estat_initial, cstat;
141
142 if (exitstat)
143 estat_initial = estat = *exitstat;
144
145 execute_command_line (command, w, &estat, cmdstat ? &cstat : NULL,
146 cmdmsg, command_len, cmdmsg_len);
147
148 if (exitstat && estat != estat_initial)
149 *exitstat = estat;
150 if (cmdstat)
151 *cmdstat = cstat;
152}
153
154
155extern void
156execute_command_line_i8 (const char *command, GFC_LOGICAL_8 *wait,
157 GFC_INTEGER_8 *exitstat, GFC_INTEGER_8 *cmdstat,
158 char *cmdmsg, gfc_charlen_type command_len,
159 gfc_charlen_type cmdmsg_len);
160export_proto(execute_command_line_i8);
161
162void
163execute_command_line_i8 (const char *command, GFC_LOGICAL_8 *wait,
164 GFC_INTEGER_8 *exitstat, GFC_INTEGER_8 *cmdstat,
165 char *cmdmsg, gfc_charlen_type command_len,
166 gfc_charlen_type cmdmsg_len)
167{
168 bool w = wait ? *wait : true;
169 int estat, estat_initial, cstat;
170
171 if (exitstat)
172 estat_initial = estat = *exitstat;
173
174 execute_command_line (command, w, &estat, cmdstat ? &cstat : NULL,
175 cmdmsg, command_len, cmdmsg_len);
176
177 if (exitstat && estat != estat_initial)
178 *exitstat = estat;
179 if (cmdstat)
180 *cmdstat = cstat;
181}