diff options
Diffstat (limited to 'libgfortran/intrinsics')
-rw-r--r-- | libgfortran/intrinsics/access.c | 17 | ||||
-rw-r--r-- | libgfortran/intrinsics/chdir.c | 24 | ||||
-rw-r--r-- | libgfortran/intrinsics/chmod.c | 31 | ||||
-rw-r--r-- | libgfortran/intrinsics/env.c | 30 | ||||
-rw-r--r-- | libgfortran/intrinsics/execute_command_line.c | 6 | ||||
-rw-r--r-- | libgfortran/intrinsics/hostnm.c | 56 | ||||
-rw-r--r-- | libgfortran/intrinsics/link.c | 75 | ||||
-rw-r--r-- | libgfortran/intrinsics/perror.c | 13 | ||||
-rw-r--r-- | libgfortran/intrinsics/random.c | 6 | ||||
-rw-r--r-- | libgfortran/intrinsics/rename.c | 70 | ||||
-rw-r--r-- | libgfortran/intrinsics/stat.c | 20 | ||||
-rw-r--r-- | libgfortran/intrinsics/symlnk.c | 68 | ||||
-rw-r--r-- | libgfortran/intrinsics/system.c | 6 | ||||
-rw-r--r-- | libgfortran/intrinsics/unlink.c | 12 |
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; } |