From 06ee2c71fbf032da003646903cb8b9f5971bce47 Mon Sep 17 00:00:00 2001 From: deuce <> Date: Wed, 26 Sep 2007 01:17:22 +0000 Subject: [PATCH] Add a popen() method to the File object. Allows read/write of a commands stdin/stdout. Only functional on Unix (planned for aspell support in fseditor) --- src/sbbs3/js_file.c | 67 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/src/sbbs3/js_file.c b/src/sbbs3/js_file.c index 62af180836..6acf1f45a1 100644 --- a/src/sbbs3/js_file.c +++ b/src/sbbs3/js_file.c @@ -59,6 +59,7 @@ typedef struct BOOL uuencoded; BOOL b64encoded; BOOL network_byte_order; + BOOL pipe; /* Opened with popen() use pclose() to close */ } private_t; @@ -181,6 +182,55 @@ js_open(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) return(JS_TRUE); } +#ifdef __unix__ +static JSBool +js_popen(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + char* mode="r+"; /* default mode */ + uintN i; + jsint bufsize=2*1024; + JSString* str; + private_t* p; + + *rval = JSVAL_FALSE; + + if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) { + JS_ReportError(cx,getprivate_failure,WHERE); + return(JS_FALSE); + } + + if(p->fp!=NULL) + return(JS_TRUE); + + for(i=0;i<argc;i++) { + if(JSVAL_IS_STRING(argv[i])) { /* mode */ + if((str = JS_ValueToString(cx, argv[i]))==NULL) { + JS_ReportError(cx,"Invalid mode specified: %s",str); + return(JS_TRUE); + } + mode=JS_GetStringBytes(str); + } + else if(JSVAL_IS_NUMBER(argv[i])) { /* bufsize */ + if(!JS_ValueToInt32(cx,argv[i],&bufsize)) + return(JS_FALSE); + } + } + SAFECOPY(p->mode,mode); + + p->fp=popen(p->name,p->mode); + if(p->fp!=NULL) { + p->pipe=TRUE; + *rval = JSVAL_TRUE; + dbprintf(FALSE, p, "popened: %s",p->name); + if(!bufsize) + setvbuf(p->fp,NULL,_IONBF,0); /* no buffering */ + else + setvbuf(p->fp,NULL,_IOFBF,bufsize); + } + + return(JS_TRUE); +} +#endif static JSBool js_close(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) @@ -195,7 +245,12 @@ js_close(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) if(p->fp==NULL) return(JS_TRUE); - fclose(p->fp); +#ifdef __unix__ + if(p->pipe) + pclose(p->fp); + else +#endif + fclose(p->fp); dbprintf(FALSE, p, "closed"); @@ -1685,6 +1740,16 @@ static jsSyncMethodSpec js_file_functions[] = { ) ,310 }, + {"popen", js_popen, 1, JSTYPE_BOOLEAN, JSDOCSTR("[mode=<tt>\"r+\"</tt>] [,buffer_length]") + ,JSDOCSTR("open pipe to command, <i>buffer_length</i> defaults to 2048 bytes, " + "mode (default: <tt>'r+'</tt>) specifies the type of access requested for the file, as follows:<br>" + "<tt>r </tt> read the programs stdout;<br>" + "<tt>w </tt> write to the programs stdin<br>" + "<tt>r+</tt> open for both reading stdout and writing stdin<br>" + "(<b>only functional on UNIX systems</b>)" + ) + ,310 + }, {"close", js_close, 0, JSTYPE_VOID, JSDOCSTR("") ,JSDOCSTR("close file") ,310 -- GitLab