summaryrefslogtreecommitdiff
path: root/libgfortran/intrinsics
diff options
context:
space:
mode:
Diffstat (limited to 'libgfortran/intrinsics')
-rw-r--r--libgfortran/intrinsics/access.c17
-rw-r--r--libgfortran/intrinsics/chdir.c24
-rw-r--r--libgfortran/intrinsics/chmod.c31
-rw-r--r--libgfortran/intrinsics/env.c30
-rw-r--r--libgfortran/intrinsics/execute_command_line.c6
-rw-r--r--libgfortran/intrinsics/hostnm.c56
-rw-r--r--libgfortran/intrinsics/link.c75
-rw-r--r--libgfortran/intrinsics/perror.c13
-rw-r--r--libgfortran/intrinsics/random.c6
-rw-r--r--libgfortran/intrinsics/rename.c70
-rw-r--r--libgfortran/intrinsics/stat.c20
-rw-r--r--libgfortran/intrinsics/symlnk.c68
-rw-r--r--libgfortran/intrinsics/system.c6
-rw-r--r--libgfortran/intrinsics/unlink.c12
14 files changed, 152 insertions, 282 deletions
diff --git a/libgfortran/intrinsics/access.c b/libgfortran/intrinsics/access.c
index a418d6703c5..65a0a103e25 100644
--- a/libgfortran/intrinsics/access.c
+++ b/libgfortran/intrinsics/access.c
@@ -2,7 +2,7 @@
Copyright (C) 2006-2014 Free Software Foundation, Inc.
Contributed by François-Xavier Coudert <coudert@clipper.ens.fr>
-This file is part of the GNU Fortran 95 runtime library (libgfortran).
+This file is part of the GNU Fortran runtime library (libgfortran).
Libgfortran is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
@@ -43,7 +43,6 @@ int
access_func (char *name, char *mode, gfc_charlen_type name_len,
gfc_charlen_type mode_len)
{
- char * file;
gfc_charlen_type i;
int m;
@@ -75,16 +74,12 @@ access_func (char *name, char *mode, gfc_charlen_type name_len,
break;
}
- /* Trim trailing spaces from NAME argument. */
- while (name_len > 0 && name[name_len - 1] == ' ')
- name_len--;
-
- /* Make a null terminated copy of the string. */
- file = gfc_alloca (name_len + 1);
- memcpy (file, name, name_len);
- file[name_len] = '\0';
+ char *path = fc_strdup (name, name_len);
/* And make the call to access(). */
- return (access (file, m) == 0 ? 0 : errno);
+ int res = (access (path, m) == 0 ? 0 : errno);
+
+ free (path);
+ return res;
}
#endif
diff --git a/libgfortran/intrinsics/chdir.c b/libgfortran/intrinsics/chdir.c
index c4933a3d5f3..87419a82e3c 100644
--- a/libgfortran/intrinsics/chdir.c
+++ b/libgfortran/intrinsics/chdir.c
@@ -44,18 +44,10 @@ void
chdir_i4_sub (char *dir, GFC_INTEGER_4 *status, gfc_charlen_type dir_len)
{
int val;
- char *str;
-
- /* Trim trailing spaces from paths. */
- while (dir_len > 0 && dir[dir_len - 1] == ' ')
- dir_len--;
-
- /* Make a null terminated copy of the strings. */
- str = gfc_alloca (dir_len + 1);
- memcpy (str, dir, dir_len);
- str[dir_len] = '\0';
+ char *str = fc_strdup (dir, dir_len);
val = chdir (str);
+ free (str);
if (status != NULL)
*status = (val == 0) ? 0 : errno;
@@ -69,18 +61,10 @@ void
chdir_i8_sub (char *dir, GFC_INTEGER_8 *status, gfc_charlen_type dir_len)
{
int val;
- char *str;
-
- /* Trim trailing spaces from paths. */
- while (dir_len > 0 && dir[dir_len - 1] == ' ')
- dir_len--;
-
- /* Make a null terminated copy of the strings. */
- str = gfc_alloca (dir_len + 1);
- memcpy (str, dir, dir_len);
- str[dir_len] = '\0';
+ char *str = fc_strdup (dir, dir_len);
val = chdir (str);
+ free (str);
if (status != NULL)
*status = (val == 0) ? 0 : errno;
diff --git a/libgfortran/intrinsics/chmod.c b/libgfortran/intrinsics/chmod.c
index acef433d92e..c42fa8c28fa 100644
--- a/libgfortran/intrinsics/chmod.c
+++ b/libgfortran/intrinsics/chmod.c
@@ -61,14 +61,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
A return value of 0 indicates success, -1 an error of chmod() while 1
indicates a mode parsing error. */
-extern int chmod_func (char *, char *, gfc_charlen_type, gfc_charlen_type);
-export_proto(chmod_func);
-int
-chmod_func (char *name, char *mode, gfc_charlen_type name_len,
- gfc_charlen_type mode_len)
+static int
+chmod_internal (char *file, char *mode, gfc_charlen_type mode_len)
{
- char * file;
int i;
bool ugo[3];
bool rwxXstugo[9];
@@ -80,15 +76,6 @@ chmod_func (char *name, char *mode, gfc_charlen_type name_len,
mode_t mode_mask, file_mode, new_mode;
struct stat stat_buf;
- /* Trim trailing spaces of the file name. */
- while (name_len > 0 && name[name_len - 1] == ' ')
- name_len--;
-
- /* Make a null terminated copy of the file name. */
- file = gfc_alloca (name_len + 1);
- memcpy (file, name, name_len);
- file[name_len] = '\0';
-
if (mode_len == 0)
return 1;
@@ -496,6 +483,20 @@ clause_done:
}
+extern int chmod_func (char *, char *, gfc_charlen_type, gfc_charlen_type);
+export_proto(chmod_func);
+
+int
+chmod_func (char *name, char *mode, gfc_charlen_type name_len,
+ gfc_charlen_type mode_len)
+{
+ char *cname = fc_strdup (name, name_len);
+ int ret = chmod_internal (cname, mode, mode_len);
+ free (cname);
+ return ret;
+}
+
+
extern void chmod_i4_sub (char *, char *, GFC_INTEGER_4 *,
gfc_charlen_type, gfc_charlen_type);
export_proto(chmod_i4_sub);
diff --git a/libgfortran/intrinsics/env.c b/libgfortran/intrinsics/env.c
index 9f4507305cd..ffdc54ac42f 100644
--- a/libgfortran/intrinsics/env.c
+++ b/libgfortran/intrinsics/env.c
@@ -52,27 +52,19 @@ PREFIX(getenv) (char * name, char * value, gfc_charlen_type name_len,
else
memset (value, ' ', value_len); /* Blank the string. */
- /* Trim trailing spaces from name. */
- while (name_len > 0 && name[name_len - 1] == ' ')
- name_len--;
-
/* Make a null terminated copy of the string. */
- name_nt = gfc_alloca (name_len + 1);
- memcpy (name_nt, name, name_len);
- name_nt[name_len] = '\0';
+ name_nt = fc_strdup (name, name_len);
res = getenv(name_nt);
+ free (name_nt);
+
/* If res is NULL, it means that the environment variable didn't
exist, so just return. */
if (res == NULL)
return;
- res_len = strlen(res);
- if (value_len < res_len)
- memcpy (value, res, value_len);
- else
- memcpy (value, res, res_len);
+ cf_strcpy (value, value_len, res);
}
@@ -127,18 +119,14 @@ get_environment_variable_i4 (char *name, char *value, GFC_INTEGER_4 *length,
}
if ((!trim_name) || *trim_name)
- {
- /* Trim trailing spaces from name. */
- while (name_len > 0 && name[name_len - 1] == ' ')
- name_len--;
- }
- /* Make a null terminated copy of the name. */
- name_nt = gfc_alloca (name_len + 1);
- memcpy (name_nt, name, name_len);
- name_nt[name_len] = '\0';
+ name_nt = fc_strdup (name, name_len);
+ else
+ name_nt = fc_strdup_notrim (name, name_len);
res = getenv(name_nt);
+ free (name_nt);
+
if (res == NULL)
stat = GFC_NAME_DOES_NOT_EXIST;
else
diff --git a/libgfortran/intrinsics/execute_command_line.c b/libgfortran/intrinsics/execute_command_line.c
index 19cc29b3c42..578b4e92658 100644
--- a/libgfortran/intrinsics/execute_command_line.c
+++ b/libgfortran/intrinsics/execute_command_line.c
@@ -61,9 +61,7 @@ execute_command_line (const char *command, bool wait, int *exitstat,
gfc_charlen_type cmdmsg_len)
{
/* Transform the Fortran string to a C string. */
- char cmd[command_len + 1];
- memcpy (cmd, command, command_len);
- cmd[command_len] = '\0';
+ char *cmd = fc_strdup (command, command_len);
/* Flush all I/O units before executing the command. */
flush_all_units();
@@ -110,6 +108,8 @@ execute_command_line (const char *command, bool wait, int *exitstat,
}
}
+ free (cmd);
+
/* Now copy back to the Fortran string if needed. */
if (cmdstat && *cmdstat > EXEC_NOERROR)
{
diff --git a/libgfortran/intrinsics/hostnm.c b/libgfortran/intrinsics/hostnm.c
index 856625826e5..c94dd775329 100644
--- a/libgfortran/intrinsics/hostnm.c
+++ b/libgfortran/intrinsics/hostnm.c
@@ -2,7 +2,7 @@
Copyright (C) 2005-2014 Free Software Foundation, Inc.
Contributed by François-Xavier Coudert <coudert@clipper.ens.fr>
-This file is part of the GNU Fortran 95 runtime library (libgfortran).
+This file is part of the GNU Fortran runtime library (libgfortran).
Libgfortran is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
@@ -32,6 +32,12 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#include <unistd.h>
#endif
+#include <limits.h>
+
+#ifndef HOST_NAME_MAX
+#define HOST_NAME_MAX 255
+#endif
+
/* Windows32 version */
#if defined __MINGW32__ && !defined HAVE_GETHOSTNAME
@@ -79,19 +85,17 @@ w32_gethostname (char *name, size_t len)
INTEGER, INTENT(OUT), OPTIONAL :: STATUS */
#ifdef HAVE_GETHOSTNAME
-extern void hostnm_i4_sub (char *, GFC_INTEGER_4 *, gfc_charlen_type);
-iexport_proto(hostnm_i4_sub);
-
-void
-hostnm_i4_sub (char *name, GFC_INTEGER_4 *status, gfc_charlen_type name_len)
+static int
+hostnm_0 (char *name, gfc_charlen_type name_len)
{
int val, i;
- char *p;
+ char p[HOST_NAME_MAX + 1];
memset (name, ' ', name_len);
- p = gfc_alloca (name_len + 1);
- val = gethostname (p, name_len);
+ size_t reqlen = sizeof (p) > (size_t) name_len + 1
+ ? (size_t) name_len + 1: sizeof (p);
+ val = gethostname (p, reqlen);
if (val == 0)
{
@@ -100,8 +104,18 @@ hostnm_i4_sub (char *name, GFC_INTEGER_4 *status, gfc_charlen_type name_len)
name[i] = p[i];
}
+ return ((val == 0) ? 0 : errno);
+}
+
+extern void hostnm_i4_sub (char *, GFC_INTEGER_4 *, gfc_charlen_type);
+iexport_proto(hostnm_i4_sub);
+
+void
+hostnm_i4_sub (char *name, GFC_INTEGER_4 *status, gfc_charlen_type name_len)
+{
+ int val = hostnm_0 (name, name_len);
if (status != NULL)
- *status = (val == 0) ? 0 : errno;
+ *status = val;
}
iexport(hostnm_i4_sub);
@@ -111,23 +125,9 @@ iexport_proto(hostnm_i8_sub);
void
hostnm_i8_sub (char *name, GFC_INTEGER_8 *status, gfc_charlen_type name_len)
{
- int val, i;
- char *p;
-
- memset (name, ' ', name_len);
- p = gfc_alloca (name_len + 1);
-
- val = gethostname (p, name_len);
-
- if (val == 0)
- {
- i = -1;
- while (i < name_len && p[++i] != '\0')
- name[i] = p[i];
- }
-
+ int val = hostnm_0 (name, name_len);
if (status != NULL)
- *status = (val == 0) ? 0 : errno;
+ *status = val;
}
iexport(hostnm_i8_sub);
@@ -137,8 +137,6 @@ export_proto(hostnm);
GFC_INTEGER_4
hostnm (char *name, gfc_charlen_type name_len)
{
- GFC_INTEGER_4 val;
- hostnm_i4_sub (name, &val, name_len);
- return val;
+ return hostnm_0 (name, name_len);
}
#endif
diff --git a/libgfortran/intrinsics/link.c b/libgfortran/intrinsics/link.c
index 2018c628a00..c6084a1cc66 100644
--- a/libgfortran/intrinsics/link.c
+++ b/libgfortran/intrinsics/link.c
@@ -2,7 +2,7 @@
Copyright (C) 2005-2014 Free Software Foundation, Inc.
Contributed by François-Xavier Coudert <coudert@clipper.ens.fr>
-This file is part of the GNU Fortran 95 runtime library (libgfortran).
+This file is part of the GNU Fortran runtime library (libgfortran).
Libgfortran is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
@@ -37,36 +37,39 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
INTEGER, INTENT(OUT), OPTIONAL :: STATUS */
#ifdef HAVE_LINK
-extern void link_i4_sub (char *, char *, GFC_INTEGER_4 *, gfc_charlen_type,
- gfc_charlen_type);
-iexport_proto(link_i4_sub);
-void
-link_i4_sub (char *path1, char *path2, GFC_INTEGER_4 *status,
- gfc_charlen_type path1_len, gfc_charlen_type path2_len)
+static int
+link_internal (char *path1, char *path2, gfc_charlen_type path1_len,
+ gfc_charlen_type path2_len)
{
int val;
char *str1, *str2;
- /* Trim trailing spaces from paths. */
- while (path1_len > 0 && path1[path1_len - 1] == ' ')
- path1_len--;
- while (path2_len > 0 && path2[path2_len - 1] == ' ')
- path2_len--;
-
/* Make a null terminated copy of the strings. */
- str1 = gfc_alloca (path1_len + 1);
- memcpy (str1, path1, path1_len);
- str1[path1_len] = '\0';
-
- str2 = gfc_alloca (path2_len + 1);
- memcpy (str2, path2, path2_len);
- str2[path2_len] = '\0';
+ str1 = fc_strdup (path1, path1_len);
+ str2 = fc_strdup (path2, path2_len);
val = link (str1, str2);
+ free (str1);
+ free (str2);
+
+ return ((val == 0) ? 0 : errno);
+}
+
+
+extern void link_i4_sub (char *, char *, GFC_INTEGER_4 *, gfc_charlen_type,
+ gfc_charlen_type);
+iexport_proto(link_i4_sub);
+
+void
+link_i4_sub (char *path1, char *path2, GFC_INTEGER_4 *status,
+ gfc_charlen_type path1_len, gfc_charlen_type path2_len)
+{
+ int val = link_internal (path1, path2, path1_len, path2_len);
+
if (status != NULL)
- *status = (val == 0) ? 0 : errno;
+ *status = val;
}
iexport(link_i4_sub);
@@ -78,28 +81,10 @@ void
link_i8_sub (char *path1, char *path2, GFC_INTEGER_8 *status,
gfc_charlen_type path1_len, gfc_charlen_type path2_len)
{
- int val;
- char *str1, *str2;
-
- /* Trim trailing spaces from paths. */
- while (path1_len > 0 && path1[path1_len - 1] == ' ')
- path1_len--;
- while (path2_len > 0 && path2[path2_len - 1] == ' ')
- path2_len--;
-
- /* Make a null terminated copy of the strings. */
- str1 = gfc_alloca (path1_len + 1);
- memcpy (str1, path1, path1_len);
- str1[path1_len] = '\0';
-
- str2 = gfc_alloca (path2_len + 1);
- memcpy (str2, path2, path2_len);
- str2[path2_len] = '\0';
-
- val = link (str1, str2);
+ int val = link_internal (path1, path2, path1_len, path2_len);
if (status != NULL)
- *status = (val == 0) ? 0 : errno;
+ *status = val;
}
iexport(link_i8_sub);
@@ -111,9 +96,7 @@ GFC_INTEGER_4
link_i4 (char *path1, char *path2, gfc_charlen_type path1_len,
gfc_charlen_type path2_len)
{
- GFC_INTEGER_4 val;
- link_i4_sub (path1, path2, &val, path1_len, path2_len);
- return val;
+ return link_internal (path1, path2, path1_len, path2_len);
}
extern GFC_INTEGER_8 link_i8 (char *, char *, gfc_charlen_type,
@@ -124,8 +107,6 @@ GFC_INTEGER_8
link_i8 (char *path1, char *path2, gfc_charlen_type path1_len,
gfc_charlen_type path2_len)
{
- GFC_INTEGER_8 val;
- link_i8_sub (path1, path2, &val, path1_len, path2_len);
- return val;
+ return link_internal (path1, path2, path1_len, path2_len);
}
#endif
diff --git a/libgfortran/intrinsics/perror.c b/libgfortran/intrinsics/perror.c
index 9a2851f5507..a8f09728706 100644
--- a/libgfortran/intrinsics/perror.c
+++ b/libgfortran/intrinsics/perror.c
@@ -37,17 +37,8 @@ iexport_proto(perror_sub);
void
perror_sub (char *string, gfc_charlen_type string_len)
{
- char * str;
-
- /* Trim trailing spaces from paths. */
- while (string_len > 0 && string[string_len - 1] == ' ')
- string_len--;
-
- /* Make a null terminated copy of the strings. */
- str = gfc_alloca (string_len + 1);
- memcpy (str, string, string_len);
- str[string_len] = '\0';
-
+ char *str = fc_strdup (string, string_len);
perror (str);
+ free (str);
}
iexport(perror_sub);
diff --git a/libgfortran/intrinsics/random.c b/libgfortran/intrinsics/random.c
index 593a6518cae..5e919292aab 100644
--- a/libgfortran/intrinsics/random.c
+++ b/libgfortran/intrinsics/random.c
@@ -666,7 +666,11 @@ void
random_seed_i4 (GFC_INTEGER_4 *size, gfc_array_i4 *put, gfc_array_i4 *get)
{
int i;
- unsigned char seed[4*kiss_size];
+
+#define KISS_MAX_SIZE 12
+ unsigned char seed[4 * KISS_MAX_SIZE];
+ _Static_assert (kiss_size <= KISS_MAX_SIZE,
+ "kiss_size must <= KISS_MAX_SIZE");
__gthread_mutex_lock (&random_lock);
diff --git a/libgfortran/intrinsics/rename.c b/libgfortran/intrinsics/rename.c
index 63901df4398..aabf8211c70 100644
--- a/libgfortran/intrinsics/rename.c
+++ b/libgfortran/intrinsics/rename.c
@@ -2,7 +2,7 @@
Copyright (C) 2005-2014 Free Software Foundation, Inc.
Contributed by François-Xavier Coudert <coudert@clipper.ens.fr>
-This file is part of the GNU Fortran 95 runtime library (libgfortran).
+This file is part of the GNU Fortran runtime library (libgfortran).
Libgfortran is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
@@ -28,6 +28,20 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#include <errno.h>
#include <string.h>
+
+static int
+rename_internal (char *path1, char *path2, gfc_charlen_type path1_len,
+ gfc_charlen_type path2_len)
+{
+ char *str1 = fc_strdup (path1, path1_len);
+ char *str2 = fc_strdup (path2, path2_len);
+ int val = rename (str1, str2);
+ free (str1);
+ free (str2);
+ return ((val == 0) ? 0 : errno);
+}
+
+
/* SUBROUTINE RENAME(PATH1, PATH2, STATUS)
CHARACTER(len=*), INTENT(IN) :: PATH1, PATH2
INTEGER, INTENT(OUT), OPTIONAL :: STATUS */
@@ -40,28 +54,9 @@ void
rename_i4_sub (char *path1, char *path2, GFC_INTEGER_4 *status,
gfc_charlen_type path1_len, gfc_charlen_type path2_len)
{
- int val;
- char *str1, *str2;
-
- /* Trim trailing spaces from paths. */
- while (path1_len > 0 && path1[path1_len - 1] == ' ')
- path1_len--;
- while (path2_len > 0 && path2[path2_len - 1] == ' ')
- path2_len--;
-
- /* Make a null terminated copy of the strings. */
- str1 = gfc_alloca (path1_len + 1);
- memcpy (str1, path1, path1_len);
- str1[path1_len] = '\0';
-
- str2 = gfc_alloca (path2_len + 1);
- memcpy (str2, path2, path2_len);
- str2[path2_len] = '\0';
-
- val = rename (str1, str2);
-
+ int val = rename_internal (path1, path2, path1_len, path2_len);
if (status != NULL)
- *status = (val == 0) ? 0 : errno;
+ *status = val;
}
iexport(rename_i4_sub);
@@ -73,28 +68,9 @@ void
rename_i8_sub (char *path1, char *path2, GFC_INTEGER_8 *status,
gfc_charlen_type path1_len, gfc_charlen_type path2_len)
{
- int val;
- char *str1, *str2;
-
- /* Trim trailing spaces from paths. */
- while (path1_len > 0 && path1[path1_len - 1] == ' ')
- path1_len--;
- while (path2_len > 0 && path2[path2_len - 1] == ' ')
- path2_len--;
-
- /* Make a null terminated copy of the strings. */
- str1 = gfc_alloca (path1_len + 1);
- memcpy (str1, path1, path1_len);
- str1[path1_len] = '\0';
-
- str2 = gfc_alloca (path2_len + 1);
- memcpy (str2, path2, path2_len);
- str2[path2_len] = '\0';
-
- val = rename (str1, str2);
-
+ int val = rename_internal (path1, path2, path1_len, path2_len);
if (status != NULL)
- *status = (val == 0) ? 0 : errno;
+ *status = val;
}
iexport(rename_i8_sub);
@@ -106,9 +82,7 @@ GFC_INTEGER_4
rename_i4 (char *path1, char *path2, gfc_charlen_type path1_len,
gfc_charlen_type path2_len)
{
- GFC_INTEGER_4 val;
- rename_i4_sub (path1, path2, &val, path1_len, path2_len);
- return val;
+ return rename_internal (path1, path2, path1_len, path2_len);
}
extern GFC_INTEGER_8 rename_i8 (char *, char *, gfc_charlen_type,
@@ -119,7 +93,5 @@ GFC_INTEGER_8
rename_i8 (char *path1, char *path2, gfc_charlen_type path1_len,
gfc_charlen_type path2_len)
{
- GFC_INTEGER_8 val;
- rename_i8_sub (path1, path2, &val, path1_len, path2_len);
- return val;
+ return rename_internal (path1, path2, path1_len, path2_len);
}
diff --git a/libgfortran/intrinsics/stat.c b/libgfortran/intrinsics/stat.c
index 1bd8b4b5a71..a60664210ec 100644
--- a/libgfortran/intrinsics/stat.c
+++ b/libgfortran/intrinsics/stat.c
@@ -67,14 +67,8 @@ stat_i4_sub_0 (char *name, gfc_array_i4 *sarray, GFC_INTEGER_4 *status,
if (GFC_DESCRIPTOR_EXTENT(sarray,0) < 13)
runtime_error ("Array size of SARRAY is too small.");
- /* Trim trailing spaces from name. */
- while (name_len > 0 && name[name_len - 1] == ' ')
- name_len--;
-
/* Make a null terminated copy of the string. */
- str = gfc_alloca (name_len + 1);
- memcpy (str, name, name_len);
- str[name_len] = '\0';
+ str = fc_strdup (name, name_len);
/* On platforms that don't provide lstat(), we use stat() instead. */
#ifdef HAVE_LSTAT
@@ -84,6 +78,8 @@ stat_i4_sub_0 (char *name, gfc_array_i4 *sarray, GFC_INTEGER_4 *status,
#endif
val = stat(str, &sb);
+ free (str);
+
if (val == 0)
{
index_type stride = GFC_DESCRIPTOR_STRIDE(sarray,0);
@@ -188,14 +184,8 @@ stat_i8_sub_0 (char *name, gfc_array_i8 *sarray, GFC_INTEGER_8 *status,
if (GFC_DESCRIPTOR_EXTENT(sarray,0) < 13)
runtime_error ("Array size of SARRAY is too small.");
- /* Trim trailing spaces from name. */
- while (name_len > 0 && name[name_len - 1] == ' ')
- name_len--;
-
/* Make a null terminated copy of the string. */
- str = gfc_alloca (name_len + 1);
- memcpy (str, name, name_len);
- str[name_len] = '\0';
+ str = fc_strdup (name, name_len);
/* On platforms that don't provide lstat(), we use stat() instead. */
#ifdef HAVE_LSTAT
@@ -205,6 +195,8 @@ stat_i8_sub_0 (char *name, gfc_array_i8 *sarray, GFC_INTEGER_8 *status,
#endif
val = stat(str, &sb);
+ free (str);
+
if (val == 0)
{
index_type stride = GFC_DESCRIPTOR_STRIDE(sarray,0);
diff --git a/libgfortran/intrinsics/symlnk.c b/libgfortran/intrinsics/symlnk.c
index 3c3d2fbba79..5c53cb75378 100644
--- a/libgfortran/intrinsics/symlnk.c
+++ b/libgfortran/intrinsics/symlnk.c
@@ -2,7 +2,7 @@
Copyright (C) 2005-2014 Free Software Foundation, Inc.
Contributed by François-Xavier Coudert <coudert@clipper.ens.fr>
-This file is part of the GNU Fortran 95 runtime library (libgfortran).
+This file is part of the GNU Fortran runtime library (libgfortran).
Libgfortran is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
@@ -37,6 +37,18 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
INTEGER, INTENT(OUT), OPTIONAL :: STATUS */
#ifdef HAVE_SYMLINK
+static int
+symlnk_internal (char *path1, char *path2, gfc_charlen_type path1_len,
+ gfc_charlen_type path2_len)
+{
+ char *str1 = fc_strdup (path1, path1_len);
+ char *str2 = fc_strdup (path2, path2_len);
+ int val = symlink (str1, str2);
+ free (str1);
+ free (str2);
+ return ((val == 0) ? 0 : errno);
+}
+
extern void symlnk_i4_sub (char *, char *, GFC_INTEGER_4 *, gfc_charlen_type,
gfc_charlen_type);
iexport_proto(symlnk_i4_sub);
@@ -45,28 +57,9 @@ void
symlnk_i4_sub (char *path1, char *path2, GFC_INTEGER_4 *status,
gfc_charlen_type path1_len, gfc_charlen_type path2_len)
{
- int val;
- char *str1, *str2;
-
- /* Trim trailing spaces from paths. */
- while (path1_len > 0 && path1[path1_len - 1] == ' ')
- path1_len--;
- while (path2_len > 0 && path2[path2_len - 1] == ' ')
- path2_len--;
-
- /* Make a null terminated copy of the strings. */
- str1 = gfc_alloca (path1_len + 1);
- memcpy (str1, path1, path1_len);
- str1[path1_len] = '\0';
-
- str2 = gfc_alloca (path2_len + 1);
- memcpy (str2, path2, path2_len);
- str2[path2_len] = '\0';
-
- val = symlink (str1, str2);
-
+ int val = symlnk_internal (path1, path2, path1_len, path2_len);
if (status != NULL)
- *status = (val == 0) ? 0 : errno;
+ *status = val;
}
iexport(symlnk_i4_sub);
@@ -78,28 +71,9 @@ void
symlnk_i8_sub (char *path1, char *path2, GFC_INTEGER_8 *status,
gfc_charlen_type path1_len, gfc_charlen_type path2_len)
{
- int val;
- char *str1, *str2;
-
- /* Trim trailing spaces from paths. */
- while (path1_len > 0 && path1[path1_len - 1] == ' ')
- path1_len--;
- while (path2_len > 0 && path2[path2_len - 1] == ' ')
- path2_len--;
-
- /* Make a null terminated copy of the strings. */
- str1 = gfc_alloca (path1_len + 1);
- memcpy (str1, path1, path1_len);
- str1[path1_len] = '\0';
-
- str2 = gfc_alloca (path2_len + 1);
- memcpy (str2, path2, path2_len);
- str2[path2_len] = '\0';
-
- val = symlink (str1, str2);
-
+ int val = symlnk_internal (path1, path2, path1_len, path2_len);
if (status != NULL)
- *status = (val == 0) ? 0 : errno;
+ *status = val;
}
iexport(symlnk_i8_sub);
@@ -111,9 +85,7 @@ GFC_INTEGER_4
symlnk_i4 (char *path1, char *path2, gfc_charlen_type path1_len,
gfc_charlen_type path2_len)
{
- GFC_INTEGER_4 val;
- symlnk_i4_sub (path1, path2, &val, path1_len, path2_len);
- return val;
+ return symlnk_internal (path1, path2, path1_len, path2_len);
}
extern GFC_INTEGER_8 symlnk_i8 (char *, char *, gfc_charlen_type,
@@ -124,8 +96,6 @@ GFC_INTEGER_8
symlnk_i8 (char *path1, char *path2, gfc_charlen_type path1_len,
gfc_charlen_type path2_len)
{
- GFC_INTEGER_8 val;
- symlnk_i8_sub (path1, path2, &val, path1_len, path2_len);
- return val;
+ return symlnk_internal (path1, path2, path1_len, path2_len);
}
#endif
diff --git a/libgfortran/intrinsics/system.c b/libgfortran/intrinsics/system.c
index d0a131d60e1..add6f4ff218 100644
--- a/libgfortran/intrinsics/system.c
+++ b/libgfortran/intrinsics/system.c
@@ -34,16 +34,14 @@ iexport_proto(system_sub);
void
system_sub (const char *fcmd, GFC_INTEGER_4 *status, gfc_charlen_type cmd_len)
{
- char cmd[cmd_len + 1];
+ char *cmd = fc_strdup (fcmd, cmd_len);
int stat;
/* Flush all I/O units before executing the command. */
flush_all_units();
- memcpy (cmd, fcmd, cmd_len);
- cmd[cmd_len] = '\0';
-
stat = system (cmd);
+ free (cmd);
if (status)
*status = stat;
}
diff --git a/libgfortran/intrinsics/unlink.c b/libgfortran/intrinsics/unlink.c
index b4de6e65cbe..2971a62e7e0 100644
--- a/libgfortran/intrinsics/unlink.c
+++ b/libgfortran/intrinsics/unlink.c
@@ -2,7 +2,7 @@
Copyright (C) 2004-2014 Free Software Foundation, Inc.
Contributed by Steven G. Kargl <kargls@comcast.net>.
-This file is part of the GNU Fortran 95 runtime library (libgfortran).
+This file is part of the GNU Fortran runtime library (libgfortran).
Libgfortran is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
@@ -46,17 +46,13 @@ unlink_i4_sub (char *name, GFC_INTEGER_4 *status, gfc_charlen_type name_len)
char *str;
GFC_INTEGER_4 stat;
- /* Trim trailing spaces from name. */
- while (name_len > 0 && name[name_len - 1] == ' ')
- name_len--;
-
/* Make a null terminated copy of the string. */
- str = gfc_alloca (name_len + 1);
- memcpy (str, name, name_len);
- str[name_len] = '\0';
+ str = fc_strdup (name, name_len);
stat = unlink (str);
+ free (str);
+
if (status != NULL)
*status = (stat == 0) ? stat : errno;
}