Skip to content
Snippets Groups Projects
Commit c20f74cc authored by rswindell's avatar rswindell
Browse files

Don't leak FILE streams for calls to js_CreateFileObject(), setting external

to TRUE meant the FILE* (created with fdopen) would never be closed. So we now
duplicate the file descriptor and get rid of the external flag, always closing
Files (FILE streams) upon File object finalize.
This fixes the resource leak leading to the eventual "Error 24 opening ..." in
the ircd.js when loaded via jsexec, on Windows. This error happened after
169 calls to load(true,...), because each background load creates 3 Files
(for stdin/out/err) and those FILE streams were never closed/freed, and
169 * 3 = 507, plus a few open files = 512, the maximum number of open file
streams in the Microsoft CRTL apparently. Thanks to Deuce for recognizing these
numbers as "magic" and pointing to the likely cause.
parent 437edfa4
No related branches found
No related tags found
No related merge requests found
...@@ -56,7 +56,6 @@ typedef struct ...@@ -56,7 +56,6 @@ typedef struct
char name[MAX_PATH+1]; char name[MAX_PATH+1];
char mode[4]; char mode[4];
uchar etx; uchar etx;
BOOL external; /* externally created, don't close */
BOOL debug; BOOL debug;
BOOL rot13; BOOL rot13;
BOOL yencoded; BOOL yencoded;
...@@ -2887,7 +2886,7 @@ static void js_finalize_file(JSContext *cx, JSObject *obj) ...@@ -2887,7 +2886,7 @@ static void js_finalize_file(JSContext *cx, JSObject *obj)
if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL)
return; return;
if(p->external==JS_FALSE && p->fp!=NULL) if(p->fp!=NULL)
fclose(p->fp); fclose(p->fp);
dbprintf(FALSE, p, "finalized: %s",p->name); dbprintf(FALSE, p, "finalized: %s",p->name);
...@@ -3024,7 +3023,7 @@ JSObject* DLLCALL js_CreateFileObject(JSContext* cx, JSObject* parent, char *nam ...@@ -3024,7 +3023,7 @@ JSObject* DLLCALL js_CreateFileObject(JSContext* cx, JSObject* parent, char *nam
{ {
JSObject* obj; JSObject* obj;
private_t* p; private_t* p;
FILE* fp = fdopen(fd, mode); FILE* fp = fdopen(dup(fd), mode);
if(fp == NULL) if(fp == NULL)
return NULL; return NULL;
...@@ -3032,17 +3031,19 @@ JSObject* DLLCALL js_CreateFileObject(JSContext* cx, JSObject* parent, char *nam ...@@ -3032,17 +3031,19 @@ JSObject* DLLCALL js_CreateFileObject(JSContext* cx, JSObject* parent, char *nam
obj = JS_DefineObject(cx, parent, name, &js_file_class, NULL obj = JS_DefineObject(cx, parent, name, &js_file_class, NULL
,JSPROP_ENUMERATE|JSPROP_READONLY); ,JSPROP_ENUMERATE|JSPROP_READONLY);
if(obj==NULL) if(obj==NULL) {
fclose(fp);
return(NULL); return(NULL);
}
if((p=(private_t*)calloc(1,sizeof(private_t)))==NULL) if((p=(private_t*)calloc(1,sizeof(private_t)))==NULL)
return(NULL); return(NULL);
p->fp=fp; p->fp=fp;
p->debug=JS_FALSE; p->debug=JS_FALSE;
p->external=JS_TRUE;
if(!JS_SetPrivate(cx, obj, p)) { if(!JS_SetPrivate(cx, obj, p)) {
fclose(fp);
dbprintf(TRUE, p, "JS_SetPrivate failed"); dbprintf(TRUE, p, "JS_SetPrivate failed");
return(NULL); return(NULL);
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment