Skip to content
Snippets Groups Projects
Commit 70a3f2e5 authored by Christophe Geuzaine's avatar Christophe Geuzaine
Browse files

Make sure to close the files left open (on purpose) in ParseFile when we exit...

Make sure to close the files left open (on purpose) in ParseFile when we exit OpenProject or when we call ClearProject.

Leaving the files open can lead to file handle exhaustion, e.g. with onelab when remeshing several hundred times. This then leads to
unpredictable socket errors.

parent 6d0291e1
Branches
Tags
No related merge requests found
......@@ -148,6 +148,8 @@ void AddToTemporaryBoundingBox(double x, double y, double z)
for(int i = 0; i < 3; i++) CTX::instance()->cg[i] = temp_bb.center()[i];
}
static std::vector<FILE*> openedFiles;
int ParseFile(std::string fileName, bool close, bool warnIfMissing)
{
#if !defined(HAVE_PARSER)
......@@ -193,6 +195,9 @@ int ParseFile(std::string fileName, bool close, bool warnIfMissing)
gmsh_yyflush();
fclose(gmsh_yyin);
}
else{
openedFiles.push_back(gmsh_yyin);
}
gmsh_yyname = old_yyname;
gmsh_yyin = old_yyin;
......@@ -424,6 +429,14 @@ void ClearProject()
#endif
for(int i = GModel::list.size() - 1; i >= 0; i--)
delete GModel::list[i];
// close the files that might have been left open by ParseFile
if(openedFiles.size()){
for(unsigned int i = 0; i < openedFiles.size(); i++)
fclose(openedFiles[i]);
openedFiles.clear();
}
new GModel();
GModel::current()->setFileName(CTX::instance()->defaultFileName);
GModel::current()->setName("");
......@@ -482,6 +495,14 @@ void OpenProject(std::string fileName)
FlGui::instance()->menu->fillRecentHistoryMenu();
#endif
}
// close the files that might have been left open by ParseFile
if(openedFiles.size()){
for(unsigned int i = 0; i < openedFiles.size(); i++)
fclose(openedFiles[i]);
openedFiles.clear();
}
CTX::instance()->lock = 0;
#if defined(HAVE_FLTK)
......
This diff is collapsed.
/* A Bison parser, made by GNU Bison 2.4.1. */
/* A Bison parser, made by GNU Bison 2.4.3. */
/* Skeleton interface for Bison's Yacc-like parsers in C
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
Free Software Foundation, Inc.
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
2009, 2010 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -183,7 +182,7 @@
typedef union YYSTYPE
{
/* Line 1676 of yacc.c */
/* Line 1685 of yacc.c */
#line 87 "Gmsh.y"
char *c;
......@@ -196,8 +195,8 @@ typedef union YYSTYPE
/* Line 1676 of yacc.c */
#line 201 "Gmsh.tab.hpp"
/* Line 1685 of yacc.c */
#line 200 "Gmsh.tab.hpp"
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
......
......@@ -2453,14 +2453,15 @@ Command :
{
if(!strcmp($1, "Include")){
std::string tmp = FixRelativePath(gmsh_yyname, $2);
// Warning: we *don't* close included files (to allow user
// functions in these files). If you need to include many many
// files and don't have functions in the files, use "Merge"
// instead: some OSes limit the number of files a process can
// open simultaneously. The right solution would be of course
// to modify FunctionManager to reopen the files instead of
// using the FILE pointer, but hey, I'm lazy...
Msg::StatusBar(2, true, "Reading '%s'...", tmp.c_str());
// Warning: we explicitly ask ParseFile not to fclose() the included
// file, in order to allow user functions definitions in these files.
// The files will be closed in the next time OpenFile terminates. If
// you need to include many many files and don't have functions in
// the files, use "Merge" instead of "Include", as some OSes limit
// the number of files a process can open simultaneously. (A better
// solution would be to modify FunctionManager to reopen the files
// instead of using the FILE pointer...)
ParseFile(tmp, false, true);
SetBoundingBox();
Msg::StatusBar(2, true, "Done reading '%s'", tmp.c_str());
......
......@@ -73,6 +73,7 @@ typedef int flex_int32_t;
typedef unsigned char flex_uint8_t;
typedef unsigned short int flex_uint16_t;
typedef unsigned int flex_uint32_t;
#endif /* ! C99 */
/* Limits of integral types. */
#ifndef INT8_MIN
......@@ -103,8 +104,6 @@ typedef unsigned int flex_uint32_t;
#define UINT32_MAX (4294967295U)
#endif
#endif /* ! C99 */
#endif /* ! FLEXINT_H */
#ifdef __cplusplus
......@@ -161,15 +160,7 @@ typedef unsigned int flex_uint32_t;
/* Size of default input buffer. */
#ifndef YY_BUF_SIZE
#ifdef __ia64__
/* On IA-64, the buffer size is 16k, not 8k.
* Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
* Ditto for the __ia64__ case accordingly.
*/
#define YY_BUF_SIZE 32768
#else
#define YY_BUF_SIZE 16384
#endif /* __ia64__ */
#endif
/* The state buf must be large enough to hold one state per character in the main buffer.
......@@ -181,7 +172,12 @@ typedef unsigned int flex_uint32_t;
typedef struct yy_buffer_state *YY_BUFFER_STATE;
#endif
extern int gmsh_yyleng;
#ifndef YY_TYPEDEF_YY_SIZE_T
#define YY_TYPEDEF_YY_SIZE_T
typedef size_t yy_size_t;
#endif
extern yy_size_t gmsh_yyleng;
extern FILE *gmsh_yyin, *gmsh_yyout;
......@@ -207,11 +203,6 @@ extern FILE *gmsh_yyin, *gmsh_yyout;
#define unput(c) yyunput( c, (yytext_ptr) )
#ifndef YY_TYPEDEF_YY_SIZE_T
#define YY_TYPEDEF_YY_SIZE_T
typedef size_t yy_size_t;
#endif
#ifndef YY_STRUCT_YY_BUFFER_STATE
#define YY_STRUCT_YY_BUFFER_STATE
struct yy_buffer_state
......@@ -229,7 +220,7 @@ struct yy_buffer_state
/* Number of characters read into yy_ch_buf, not including EOB
* characters.
*/
int yy_n_chars;
yy_size_t yy_n_chars;
/* Whether we "own" the buffer - i.e., we know we created it,
* and can realloc() it to grow it, and should free() it to
......@@ -299,8 +290,8 @@ static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
/* yy_hold_char holds the character lost when gmsh_yytext is formed. */
static char yy_hold_char;
static int yy_n_chars; /* number of characters read into yy_ch_buf */
int gmsh_yyleng;
static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */
yy_size_t gmsh_yyleng;
/* Points to current character in buffer. */
static char *yy_c_buf_p = (char *) 0;
......@@ -328,7 +319,7 @@ static void gmsh_yy_init_buffer (YY_BUFFER_STATE b,FILE *file );
YY_BUFFER_STATE gmsh_yy_scan_buffer (char *base,yy_size_t size );
YY_BUFFER_STATE gmsh_yy_scan_string (yyconst char *yy_str );
YY_BUFFER_STATE gmsh_yy_scan_bytes (yyconst char *bytes,int len );
YY_BUFFER_STATE gmsh_yy_scan_bytes (yyconst char *bytes,yy_size_t len );
void *gmsh_yyalloc (yy_size_t );
void *gmsh_yyrealloc (void *,yy_size_t );
......@@ -954,7 +945,7 @@ void skipline(void);
#define YY_NO_UNISTD_H
#endif
#line 958 "Gmsh.yy.cpp"
#line 949 "Gmsh.yy.cpp"
#define INITIAL 0
......@@ -993,7 +984,7 @@ FILE *gmsh_yyget_out (void );
void gmsh_yyset_out (FILE * out_str );
int gmsh_yyget_leng (void );
yy_size_t gmsh_yyget_leng (void );
char *gmsh_yyget_text (void );
......@@ -1035,12 +1026,7 @@ static int input (void );
/* Amount of stuff to slurp up with each read. */
#ifndef YY_READ_BUF_SIZE
#ifdef __ia64__
/* On IA-64, the buffer size is 16k, not 8k */
#define YY_READ_BUF_SIZE 16384
#else
#define YY_READ_BUF_SIZE 8192
#endif /* __ia64__ */
#endif
/* Copy whatever the last rule matched to the standard output. */
......@@ -1048,7 +1034,7 @@ static int input (void );
/* This used to be an fputs(), but since the string might contain NUL's,
* we now use fwrite().
*/
#define ECHO do { if (fwrite( gmsh_yytext, gmsh_yyleng, 1, gmsh_yyout )) {} } while (0)
#define ECHO fwrite( gmsh_yytext, gmsh_yyleng, 1, gmsh_yyout )
#endif
/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
......@@ -1059,7 +1045,7 @@ static int input (void );
if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
{ \
int c = '*'; \
size_t n; \
yy_size_t n; \
for ( n = 0; n < max_size && \
(c = getc( gmsh_yyin )) != EOF && c != '\n'; ++n ) \
buf[n] = (char) c; \
......@@ -1144,7 +1130,7 @@ YY_DECL
#line 49 "Gmsh.l"
#line 1148 "Gmsh.yy.cpp"
#line 1134 "Gmsh.yy.cpp"
if ( !(yy_init) )
{
......@@ -2009,7 +1995,7 @@ YY_RULE_SETUP
#line 233 "Gmsh.l"
ECHO;
YY_BREAK
#line 2013 "Gmsh.yy.cpp"
#line 1999 "Gmsh.yy.cpp"
case YY_STATE_EOF(INITIAL):
yyterminate();
......@@ -2195,7 +2181,7 @@ static int yy_get_next_buffer (void)
else
{
int num_to_read =
yy_size_t num_to_read =
YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
while ( num_to_read <= 0 )
......@@ -2209,7 +2195,7 @@ static int yy_get_next_buffer (void)
if ( b->yy_is_our_buffer )
{
int new_size = b->yy_buf_size * 2;
yy_size_t new_size = b->yy_buf_size * 2;
if ( new_size <= 0 )
b->yy_buf_size += b->yy_buf_size / 8;
......@@ -2240,7 +2226,7 @@ static int yy_get_next_buffer (void)
/* Read in more data. */
YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
(yy_n_chars), (size_t) num_to_read );
(yy_n_chars), num_to_read );
YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
}
......@@ -2350,7 +2336,7 @@ static int yy_get_next_buffer (void)
if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
{ /* need to shift things up to make room */
/* +2 for EOB chars. */
register int number_to_move = (yy_n_chars) + 2;
register yy_size_t number_to_move = (yy_n_chars) + 2;
register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
register char *source =
......@@ -2399,7 +2385,7 @@ static int yy_get_next_buffer (void)
else
{ /* need more input */
int offset = (yy_c_buf_p) - (yytext_ptr);
yy_size_t offset = (yy_c_buf_p) - (yytext_ptr);
++(yy_c_buf_p);
switch ( yy_get_next_buffer( ) )
......@@ -2423,7 +2409,7 @@ static int yy_get_next_buffer (void)
case EOB_ACT_END_OF_FILE:
{
if ( gmsh_yywrap( ) )
return EOF;
return 0;
if ( ! (yy_did_buffer_switch_on_eof) )
YY_NEW_FILE;
......@@ -2675,7 +2661,7 @@ void gmsh_yypop_buffer_state (void)
*/
static void gmsh_yyensure_buffer_stack (void)
{
int num_to_alloc;
yy_size_t num_to_alloc;
if (!(yy_buffer_stack)) {
......@@ -2767,17 +2753,16 @@ YY_BUFFER_STATE gmsh_yy_scan_string (yyconst char * yystr )
/** Setup the input buffer state to scan the given bytes. The next call to gmsh_yylex() will
* scan from a @e copy of @a bytes.
* @param yybytes the byte buffer to scan
* @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
* @param bytes the byte buffer to scan
* @param len the number of bytes in the buffer pointed to by @a bytes.
*
* @return the newly allocated buffer state object.
*/
YY_BUFFER_STATE gmsh_yy_scan_bytes (yyconst char * yybytes, int _yybytes_len )
YY_BUFFER_STATE gmsh_yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len )
{
YY_BUFFER_STATE b;
char *buf;
yy_size_t n;
int i;
yy_size_t n, i;
/* Get memory for full buffer, including space for trailing EOB's. */
n = _yybytes_len + 2;
......@@ -2859,7 +2844,7 @@ FILE *gmsh_yyget_out (void)
/** Get the length of the current token.
*
*/
int gmsh_yyget_leng (void)
yy_size_t gmsh_yyget_leng (void)
{
return gmsh_yyleng;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment