*** empty log message ***
git-svn-id: svn://10.0.0.236/trunk@17356 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
edf72c7977
commit
939e901bce
@ -28,6 +28,9 @@
|
||||
# include <unistd.h>
|
||||
#else
|
||||
# include "direct.h"
|
||||
# include <io.h>
|
||||
# include <sys/types.h>
|
||||
# include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
#include "jsapi.h"
|
||||
@ -73,10 +76,22 @@ typedef enum JSFileErrNum {
|
||||
#define utfstring "binary"
|
||||
#define unicodestring "unicode"
|
||||
|
||||
/* Platform dependent code goes here. */
|
||||
#define MAX_PATH_LENGTH 1024
|
||||
#define MSG_SIZE 256
|
||||
#define URL_PREFIX "file://"
|
||||
|
||||
static JSBool
|
||||
filenameHasAPipe(char *filename){
|
||||
#ifdef XP_MAC
|
||||
/* pipes are not supported on the MAC */
|
||||
return JS_FALSE;
|
||||
#else
|
||||
if(!filename) return JS_FALSE;
|
||||
return filename[0]==PIPE_SYMBOL || filename[strlen(filename)-1]==PIPE_SYMBOL;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Platform dependent code goes here. */
|
||||
#ifdef XP_MAC
|
||||
# define LINEBREAK "\012"
|
||||
# define LINEBREAK_LEN 1
|
||||
@ -90,13 +105,6 @@ isAbsolute(char*name)
|
||||
return (name[0]!=FILESEPARATOR);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
isRoot(char*name)
|
||||
{
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* We assume: base is a valid absolute path, not ending with :
|
||||
name is a valid relative path. */
|
||||
static char *
|
||||
@ -162,7 +170,6 @@ fileDirectoryName(JSContext *cx, char * pathname)
|
||||
# define CURRENT_DIR "c:\\"
|
||||
# define POPEN _popen
|
||||
# define PCLOSE _pclose
|
||||
# define ACCESS _access
|
||||
|
||||
static JSBool
|
||||
isAbsolute(char*name)
|
||||
@ -176,16 +183,6 @@ isAbsolute(char*name)
|
||||
return JS_FALSE; /* First approximation, ignore "/tmp" case.. */
|
||||
}
|
||||
|
||||
/* x: or x:\ */
|
||||
static JSBool
|
||||
isRoot(char *name)
|
||||
{
|
||||
int len=strlen(name);
|
||||
|
||||
return (len==2||(len==3 && name[2]==FILESEPARATOR))&&(name[1]==':');
|
||||
}
|
||||
|
||||
|
||||
/* We assume: base is a valid absolute path, starting with x:, ending with /.
|
||||
name is a valid relative path, and may have a drive selector. */
|
||||
static char *
|
||||
@ -287,7 +284,6 @@ fileDirectoryName(JSContext *cx, char * pathname)
|
||||
# define CURRENT_DIR "/"
|
||||
# define POPEN popen
|
||||
# define PCLOSE pclose
|
||||
# define ACCESS access
|
||||
|
||||
static JSBool
|
||||
isAbsolute(char*name)
|
||||
@ -295,13 +291,6 @@ isAbsolute(char*name)
|
||||
return (name[0]==FILESEPARATOR);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
isRoot(char *name)
|
||||
{
|
||||
return !strcmp(name, FILESEPARATOR);
|
||||
}
|
||||
|
||||
|
||||
/* We assume: base is a valid absolute path[, ending with /]. name is a valid relative path. */
|
||||
static char *
|
||||
combinePath(JSContext *cx, char *base, char*name)
|
||||
@ -676,9 +665,9 @@ typedef struct JSFile {
|
||||
jsint nbBytesInBuf; /* number of bytes stored in the buffer above */
|
||||
jschar charBuffer; /* character read in advance by readln ( mac files only ) */
|
||||
JSBool charBufferUsed; /* flag indicating if the buffer above is being used */
|
||||
JSBool randomAccess; /* can the file be randomly accessed? false for stdin, and
|
||||
JSBool hasRandomAccess; /* can the file be randomly accessed? false for stdin, and
|
||||
UTF-encoded files. */
|
||||
JSBool autoflush; /* should we force a flush for each line break? */
|
||||
JSBool hasAutoflush; /* should we force a flush for each line break? */
|
||||
JSBool isNative; /* if the file is using OS-specific file FILE type */
|
||||
|
||||
union{ /* anonymous union */
|
||||
@ -690,7 +679,7 @@ typedef struct JSFile {
|
||||
|
||||
/* a few forward declarations... */
|
||||
static JSClass file_class;
|
||||
JS_EXPORT_API(JSObject*) js_NewFileObject(JSContext *cx, char *bytes);
|
||||
JS_EXPORT_API(JSObject*) js_NewFileObject(JSContext *cx, char *filename);
|
||||
JS_EXPORT_API(JSObject*) js_NewFileObjectFromFILEFromFILE(JSContext *cx, FILE *f, char *filename, JSBool open);
|
||||
static JSBool file_open(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
static JSBool file_close(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
@ -701,19 +690,22 @@ static JSBool file_close(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
||||
*
|
||||
* strcasecmp is in strings.h, but on windows it's called _stricmp...
|
||||
* will need to #ifdef this
|
||||
* */
|
||||
*/
|
||||
|
||||
static int32
|
||||
js_FileHasOption(char *options, char *name)
|
||||
js_FileHasOption(JSContext *cx, char *oldoptions, char *name)
|
||||
{
|
||||
char *comma, *equal;
|
||||
char *comma, *equal, *current;
|
||||
char *options = JS_strdup(cx, oldoptions);
|
||||
int32 found = 0;
|
||||
|
||||
current = options;
|
||||
for (;;) {
|
||||
comma = strchr(options, ', ');
|
||||
comma = strchr(current, ', ');
|
||||
if (comma) *comma = '\0';
|
||||
equal = strchr(options, ' = ');
|
||||
equal = strchr(current, ' = ');
|
||||
if (equal) *equal = '\0';
|
||||
if (strcmp(options, name) == 0) {
|
||||
if (strcmp(current, name) == 0) {
|
||||
if (!equal || strcmp(equal + 1, "yes") == 0)
|
||||
found = 1;
|
||||
else
|
||||
@ -723,8 +715,9 @@ js_FileHasOption(char *options, char *name)
|
||||
if (comma) *comma = ',';
|
||||
if (found || !comma)
|
||||
break;
|
||||
options = comma + 1;
|
||||
current = comma + 1;
|
||||
}
|
||||
JS_free(cx, options);
|
||||
return found;
|
||||
}
|
||||
|
||||
@ -741,7 +734,7 @@ js_ResetAttributes(JSFile * file){
|
||||
file->isOpen = JS_FALSE;
|
||||
file->handle = NULL;
|
||||
file->nativehandle = NULL;
|
||||
file->randomAccess = JS_TRUE; /* innocent until proven guilty */
|
||||
file->hasRandomAccess = JS_TRUE; /* innocent until proven guilty */
|
||||
file->isNative = JS_FALSE;
|
||||
file->isAPipe = JS_FALSE;
|
||||
js_ResetBuffers(file);
|
||||
@ -769,6 +762,7 @@ static int32
|
||||
js_BufferedRead(JSFile * f, char *buf, int32 len)
|
||||
{
|
||||
int32 count = 0;
|
||||
|
||||
while (f->nbBytesInBuf>0&&len>0) {
|
||||
buf[0] = f->byteBuffer[0];
|
||||
f->byteBuffer[0] = f->byteBuffer[1];
|
||||
@ -778,12 +772,11 @@ js_BufferedRead(JSFile * f, char *buf, int32 len)
|
||||
buf+=1;
|
||||
count++;
|
||||
}
|
||||
|
||||
if (len>0) {
|
||||
if (f->handle) {
|
||||
count+=PR_Read(f->handle, buf, len);
|
||||
} else {
|
||||
count+=fread(buf, 1, len, f->nativehandle);
|
||||
}
|
||||
count+= (!f->isNative)?
|
||||
PR_Read(f->handle, buf, len):
|
||||
fread(buf, 1, len, f->nativehandle);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
@ -871,11 +864,9 @@ js_FileSkip(JSFile * f, int32 len, int32 mode)
|
||||
|
||||
switch (mode) {
|
||||
case ASCII:
|
||||
if (f->handle) {
|
||||
count = PR_Seek(f->handle, len, PR_SEEK_CUR);
|
||||
} else {
|
||||
count = fseek(f->nativehandle, len, SEEK_CUR);
|
||||
}
|
||||
count = (!f->isNative)?
|
||||
PR_Seek(f->handle, len, PR_SEEK_CUR):
|
||||
fseek(f->nativehandle, len, SEEK_CUR);
|
||||
break;
|
||||
case UTF8:
|
||||
remainder = 0;
|
||||
@ -911,11 +902,9 @@ js_FileSkip(JSFile * f, int32 len, int32 mode)
|
||||
}
|
||||
break;
|
||||
case UCS2:
|
||||
if (f->handle) {
|
||||
count = PR_Seek(f->handle, len*2, PR_SEEK_CUR)/2;
|
||||
} else {
|
||||
count = fseek(f->nativehandle, len*2, SEEK_CUR)/2;
|
||||
}
|
||||
count = (!f->isNative)?
|
||||
PR_Seek(f->handle, len*2, PR_SEEK_CUR)/2:
|
||||
fseek(f->nativehandle, len*2, SEEK_CUR)/2;
|
||||
break;
|
||||
}
|
||||
return count;
|
||||
@ -935,11 +924,11 @@ js_FileWrite(JSContext *cx, JSFile* f, jschar*buf, int32 len, int32 mode)
|
||||
for (i = 0; i<len; i++) {
|
||||
aux[i]=buf[i]%256;
|
||||
}
|
||||
if (f->handle) {
|
||||
count = PR_Write(f->handle, aux, len);
|
||||
} else {
|
||||
count = fwrite(aux, 1, len, f->nativehandle);
|
||||
}
|
||||
|
||||
count = (!f->isNative)?
|
||||
PR_Write(f->handle, aux, len):
|
||||
fwrite(aux, 1, len, f->nativehandle);
|
||||
|
||||
if (count==-1) {
|
||||
JS_free(cx, aux);
|
||||
return 0;
|
||||
@ -958,11 +947,10 @@ js_FileWrite(JSContext *cx, JSFile* f, jschar*buf, int32 len, int32 mode)
|
||||
}
|
||||
i+=j;
|
||||
}
|
||||
if (f->handle) {
|
||||
j = PR_Write(f->handle, utfbuf, i);
|
||||
} else {
|
||||
j = fwrite(utfbuf, 1, i, f->nativehandle);
|
||||
}
|
||||
j = (!f->isNative)?
|
||||
PR_Write(f->handle, utfbuf, i):
|
||||
fwrite(utfbuf, 1, i, f->nativehandle);
|
||||
|
||||
if (j<i) {
|
||||
JS_free(cx, utfbuf);
|
||||
return 0;
|
||||
@ -970,11 +958,10 @@ js_FileWrite(JSContext *cx, JSFile* f, jschar*buf, int32 len, int32 mode)
|
||||
JS_free(cx, utfbuf);
|
||||
break;
|
||||
case UCS2:
|
||||
if (f->handle) {
|
||||
count = PR_Write(f->handle, buf, len*2)>>1;
|
||||
} else {
|
||||
count = fwrite(buf, 1, len*2, f->nativehandle)>>1;
|
||||
}
|
||||
count = (!f->isNative)?
|
||||
PR_Write(f->handle, buf, len*2)>>1:
|
||||
fwrite(buf, 1, len*2, f->nativehandle)>>1;
|
||||
|
||||
if (count==-1) {
|
||||
return 0;
|
||||
}
|
||||
@ -991,43 +978,41 @@ js_exists(JSFile *file)
|
||||
if(!file->isNative){
|
||||
return (PR_Access(file->path, PR_ACCESS_EXISTS)==PR_SUCCESS);
|
||||
}else{
|
||||
/* TODO: */
|
||||
return (ACCESS(file->path, PR_ACCESS_EXISTS)==PR_SUCCESS);
|
||||
return (access(file->path, PR_ACCESS_EXISTS)==PR_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
static JSBool
|
||||
js_canRead(JSFile *file)
|
||||
{
|
||||
|
||||
if(!(file->mode&PR_RDONLY)) return JS_FALSE;
|
||||
if(file->isOpen&&!(file->mode&PR_RDONLY)) return JS_FALSE;
|
||||
/* SECURITY */
|
||||
if(!file->isNative){
|
||||
return (PR_Access(file->path, PR_ACCESS_EXISTS)==PR_SUCCESS);
|
||||
return (PR_Access(file->path, PR_ACCESS_READ_OK)==PR_SUCCESS);
|
||||
}else{
|
||||
return (ACCESS(file->path, PR_ACCESS_READ_OK)==PR_SUCCESS);
|
||||
return (access(file->path, PR_ACCESS_READ_OK)==PR_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
static JSBool
|
||||
js_canWrite(JSFile *file)
|
||||
{
|
||||
if(!(file->mode&PR_WRONLY)) return JS_FALSE;
|
||||
if(file->isOpen&&!(file->mode&PR_WRONLY)) return JS_FALSE;
|
||||
/* SECURITY */
|
||||
if(!file->isNative){
|
||||
return (PR_Access(file->path, PR_ACCESS_EXISTS)==PR_SUCCESS);
|
||||
return (PR_Access(file->path, PR_ACCESS_WRITE_OK)==PR_SUCCESS);
|
||||
}else{
|
||||
return (ACCESS(file->path, PR_ACCESS_WRITE_OK)==PR_SUCCESS);
|
||||
return (access(file->path, PR_ACCESS_WRITE_OK)==PR_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
static JSBool
|
||||
js_isFile(JSFile *file)
|
||||
{
|
||||
PRFileInfo info;
|
||||
|
||||
/* SECURITY */
|
||||
if(!file->isNative){
|
||||
PRFileInfo info;
|
||||
|
||||
if ((file->isOpen)?
|
||||
PR_GetOpenFileInfo(file->handle, &info):
|
||||
PR_GetFileInfo(file->path, &info)!=PR_SUCCESS){
|
||||
@ -1036,17 +1021,22 @@ js_isFile(JSFile *file)
|
||||
}else
|
||||
return (info.type==PR_FILE_FILE);
|
||||
}else{
|
||||
/* TODO: can't really do much at this point */
|
||||
struct stat buf;
|
||||
if(stat(file->path, &buf)){
|
||||
/* TODO: report error */
|
||||
return JS_FALSE;
|
||||
}
|
||||
return (buf.st_mode&_S_IFREG);
|
||||
}
|
||||
}
|
||||
|
||||
static JSBool
|
||||
js_isDirectory(JSFile *file)
|
||||
{
|
||||
PRFileInfo info;
|
||||
|
||||
/* SECURITY */
|
||||
if(!file->isNative){
|
||||
PRFileInfo info;
|
||||
|
||||
if ((file->isOpen)?
|
||||
PR_GetOpenFileInfo(file->handle, &info):
|
||||
PR_GetFileInfo(file->path, &info)!=PR_SUCCESS){
|
||||
@ -1055,10 +1045,42 @@ js_isDirectory(JSFile *file)
|
||||
}else
|
||||
return (info.type==PR_FILE_DIRECTORY);
|
||||
}else{
|
||||
/* TODO: can't really do much at this point */
|
||||
struct stat buf;
|
||||
if(stat(file->path, &buf )){
|
||||
/* TODO: report error */
|
||||
return JS_FALSE;
|
||||
}
|
||||
return (buf.st_mode&_S_IFDIR);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
js_size(JSFile *file)
|
||||
{
|
||||
/* SECURITY */
|
||||
if(!file->isNative){
|
||||
PRFileInfo info;
|
||||
|
||||
if ((file->isOpen)?
|
||||
PR_GetOpenFileInfo(file->handle, &info):
|
||||
PR_GetFileInfo(file->path, &info)!=PR_SUCCESS){
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSFILEMSG_CANNOT_ACCESS_FILE_STATUS, file->path);
|
||||
return -1;
|
||||
}else
|
||||
return info.size;
|
||||
}else{
|
||||
struct stat buf;
|
||||
if(stat(file->path, &buf)){
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSFILEMSG_CANNOT_ACCESS_FILE_STATUS, file->path);
|
||||
return -1;
|
||||
}else
|
||||
return buf.st_size;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------- File methods ------------------------------ */
|
||||
static JSBool
|
||||
file_open(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
@ -1075,6 +1097,8 @@ file_open(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
|
||||
/* A native file that is already open */
|
||||
if(file->isOpen && file->isNative){
|
||||
JS_ReportWarning(cx, "Native file %s is already open, proceeding", file->path);
|
||||
*rval = JSVAL_TRUE;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
@ -1111,17 +1135,16 @@ file_open(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
/* Process the mode */
|
||||
mask = 0;
|
||||
/* TODO: this is pretty ugly, BTW, we walk thru the string too many times */
|
||||
mask|=(js_FileHasOption(mode, "readOnly"))? PR_RDONLY : 0;
|
||||
mask|=(js_FileHasOption(mode, "writeOnly"))? PR_WRONLY : 0;
|
||||
mask|=(js_FileHasOption(mode, "readWrite"))? PR_RDWR : 0;
|
||||
mask|=(js_FileHasOption(mode, "append"))? PR_APPEND : 0;
|
||||
mask|=(js_FileHasOption(mode, "create"))? PR_CREATE_FILE : 0;
|
||||
mask|=(js_FileHasOption(mode, "truncate"))? PR_TRUNCATE : 0;
|
||||
mask|=(js_FileHasOption(mode, "replace"))? PR_TRUNCATE : 0;
|
||||
mask|=(js_FileHasOption(cx, mode, "readOnly"))? PR_RDONLY : 0;
|
||||
mask|=(js_FileHasOption(cx, mode, "writeOnly"))? PR_WRONLY : 0;
|
||||
mask|=(js_FileHasOption(cx, mode, "readWrite"))? PR_RDWR : 0;
|
||||
mask|=(js_FileHasOption(cx, mode, "append"))? PR_APPEND : 0;
|
||||
mask|=(js_FileHasOption(cx, mode, "create"))? PR_CREATE_FILE : 0;
|
||||
mask|=(js_FileHasOption(cx, mode, "replace"))? PR_TRUNCATE : 0;
|
||||
|
||||
if ((mask&(PR_RDONLY|PR_WRONLY))==0) mask|=PR_RDWR;
|
||||
|
||||
file->autoflush|=(js_FileHasOption(mode, "autoflush"));
|
||||
file->hasAutoflush|=(js_FileHasOption(cx, mode, "hasAutoflush"));
|
||||
|
||||
JS_free(cx, mode);
|
||||
|
||||
@ -1150,7 +1173,7 @@ file_open(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
file->type = type;
|
||||
file->mode = mask;
|
||||
file->nativehandle = NULL;
|
||||
file->randomAccess = (type!=UTF8);
|
||||
file->hasRandomAccess = (type!=UTF8);
|
||||
|
||||
/*
|
||||
Deal with pipes here. We can't use NSPR for pipes,
|
||||
@ -1204,11 +1227,13 @@ file_open(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
|
||||
/* Set the open flag and return result */
|
||||
if (file->handle==NULL && file->nativehandle==NULL){
|
||||
file->isOpen = JS_TRUE;
|
||||
/* TODO: error */
|
||||
file->isOpen = JS_FALSE;
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSFILEMSG_OPEN_FAILED, file->path);
|
||||
return JS_FALSE;
|
||||
}else{
|
||||
file->isOpen = JS_TRUE;
|
||||
*rval = JSVAL_TRUE;
|
||||
return JS_TRUE;
|
||||
}
|
||||
}
|
||||
@ -1229,12 +1254,15 @@ file_close(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
if ((!file->isNative)?
|
||||
PR_Close(file->handle):
|
||||
fclose(file->nativehandle)!=0){
|
||||
/* TODO: error reporting */
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSFILEMSG_CLOSE_FAILED, file->path);
|
||||
|
||||
return JS_FALSE;
|
||||
}
|
||||
}else{
|
||||
if(PCLOSE(file->nativehandle)==-1){
|
||||
/* TODO: error */
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSFILEMSG_PCLOSE_FAILED, file->path);
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
@ -1252,12 +1280,24 @@ file_remove(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);;
|
||||
|
||||
/* SECURITY */
|
||||
if ((js_isDirectory(file) ? PR_RmDir(file->path) : PR_Delete(file->path))==PR_SUCCESS) {
|
||||
js_ResetAttributes(file);
|
||||
*rval = JSVAL_TRUE;
|
||||
} else {
|
||||
/* TODO: error */
|
||||
return JS_FALSE;
|
||||
if(!file->isNative){
|
||||
if ((js_isDirectory(file) ? PR_RmDir(file->path) : PR_Delete(file->path))==PR_SUCCESS) {
|
||||
js_ResetAttributes(file);
|
||||
*rval = JSVAL_TRUE;
|
||||
} else {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSFILEMSG_REMOVE_FAILED, file->path);
|
||||
return JS_FALSE;
|
||||
}
|
||||
}else{
|
||||
if ((js_isDirectory(file) ? rmdir(file->path) : remove(file->path))==PR_SUCCESS) {
|
||||
js_ResetAttributes(file);
|
||||
*rval = JSVAL_TRUE;
|
||||
} else {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSFILEMSG_REMOVE_FAILED, file->path);
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1267,14 +1307,17 @@ file_copyTo(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
JSFile *file;
|
||||
char *dest;
|
||||
PRFileDesc *handle;
|
||||
PRFileInfo info;
|
||||
PRFileDesc *handle = NULL;
|
||||
char *buffer;
|
||||
uint32 count;
|
||||
uint32 count, size;
|
||||
JSBool fileInitiallyOpen=JS_FALSE;
|
||||
|
||||
/* SECURITY */
|
||||
|
||||
if (argc!=1){
|
||||
/* TODO: error reporting */
|
||||
return JS_FALSE;
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSFILEMSG_EXPECTS_ONE_ARG_ERROR, "copyTo", argc);
|
||||
goto out;
|
||||
}
|
||||
|
||||
file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
|
||||
@ -1291,81 +1334,82 @@ file_copyTo(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
|
||||
/* open a closed file */
|
||||
if(!file->isOpen){
|
||||
file->handle = PR_Open(file->path, PR_RDONLY, 0644);
|
||||
|
||||
if(file->isNative){
|
||||
/* TODO: error */
|
||||
return JS_FALSE;
|
||||
if(!file->isNative){
|
||||
file->handle = PR_Open(file->path, PR_RDONLY, 0644);
|
||||
}else{
|
||||
file->nativehandle = fopen(file->path, "r");
|
||||
}
|
||||
}
|
||||
}else
|
||||
fileInitiallyOpen = JS_TRUE;
|
||||
|
||||
if (file->handle==NULL && file->nativehandle==NULL){
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSFILEMSG_OPEN_FAILED, file->path);
|
||||
return JS_FALSE;
|
||||
}else
|
||||
file->open = JS_TRUE;
|
||||
|
||||
/* SECURITY */
|
||||
handle = PR_Open(dest, PR_WRONLY|PR_CREATE_FILE|PR_TRUNCATE, 0644);
|
||||
|
||||
if(!handle){
|
||||
/* TODO: error */
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
if (PR_GetOpenFileInfo(file->handle, &info)==PR_FAILURE) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSFILEMSG_CANNOT_ACCESS_FILE_INFO_ERROR, file->path);
|
||||
return JS_FALSE;
|
||||
JSFILEMSG_OPEN_FAILED, dest);
|
||||
goto out;
|
||||
}
|
||||
|
||||
buffer = JS_malloc(cx, info.size);
|
||||
if ((size=js_size(file))!=-1) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
count = PR_Read(file->handle, buffer, info.size);
|
||||
buffer = JS_malloc(cx, size);
|
||||
|
||||
if (count!=info.size) {
|
||||
count = (!file->isNative)?
|
||||
PR_Read(file->handle, buffer, size):
|
||||
fread(buffer, 1, size, file->nativehandle);
|
||||
|
||||
/* reading panic */
|
||||
if (count!=size) {
|
||||
JS_free(cx, buffer);
|
||||
if(PR_Close(file->handle)!=PR_SUCCESS){
|
||||
/* TODO: error */
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
if(PR_Close(handle)!=PR_SUCCESS){
|
||||
/* TODO: error */
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSFILEMSG_COPY_READ_ERROR, file->path);
|
||||
return JS_FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
count = PR_Write(handle, buffer, info.size);
|
||||
count = PR_Write(handle, buffer, size);
|
||||
|
||||
if (count!=info.size) {
|
||||
/* writing panic */
|
||||
if (count!=size) {
|
||||
JS_free(cx, buffer);
|
||||
if(PR_Close(file->handle)!=PR_SUCCESS){
|
||||
/* TODO: error */
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
if(PR_Close(handle)!=PR_SUCCESS){
|
||||
/* TODO: error */
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSFILEMSG_COPY_WRITE_ERROR, file->path);
|
||||
return JS_FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
JS_free(cx, buffer);
|
||||
if(PR_Close(file->handle)!=PR_SUCCESS){
|
||||
if(((!file->isNative)?PR_Close(file->handle):fclose(file->nativehandle))!=PR_SUCCESS){
|
||||
/* TODO: error */
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
if(PR_Close(handle)!=PR_SUCCESS){
|
||||
/* TODO: error */
|
||||
return JS_FALSE;
|
||||
}
|
||||
} goto out;
|
||||
|
||||
*rval = JSVAL_TRUE;
|
||||
return JS_TRUE;
|
||||
out:
|
||||
if(file->open && !fileInitiallyOpen){
|
||||
if((!file->isNative)?PR_Close(file->handle):fclose(file->nativehandle)!=PR_SUCCESS){
|
||||
JS_ReportWarning(cx, "Can't close %s, proceeding", file->path);
|
||||
}
|
||||
}
|
||||
|
||||
if(handle && PR_Close(handle)!=PR_SUCCESS){
|
||||
JS_ReportWarning(cx, "Can't close %s, proceeding", dest);
|
||||
}
|
||||
|
||||
*rval = JSVAL_FALSE;
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
@ -1376,7 +1420,7 @@ file_renameTo(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval
|
||||
|
||||
if (argc<1) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSFILEMSG_RENAME_EXPECTS_ONE_ARG_ERROR);
|
||||
JSFILEMSG_EXPECTS_ONE_ARG_ERROR, "rename", argc);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
@ -1385,7 +1429,7 @@ file_renameTo(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval
|
||||
dest = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
|
||||
|
||||
/* SECURITY */
|
||||
if (PR_Rename(file->path, dest)==PR_SUCCESS){
|
||||
if (((!file->isNative)?PR_Rename(file->path, dest):rename(file->path, dest))==PR_SUCCESS){
|
||||
*rval = JSVAL_TRUE;
|
||||
return JS_TRUE;
|
||||
}else{
|
||||
@ -1411,6 +1455,7 @@ file_flush(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
if ((!file->isNative)?PR_Sync(file->handle):fflush(file->nativehandle)==PR_SUCCESS)
|
||||
*rval = JSVAL_TRUE;
|
||||
else{
|
||||
/* TODO: report error */
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
@ -1449,7 +1494,6 @@ file_writeln(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
JSFile *file;
|
||||
JSString *str;
|
||||
jsint count;
|
||||
|
||||
file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
|
||||
|
||||
@ -1457,15 +1501,14 @@ file_writeln(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
if(!file_write(cx, obj, argc, argv, rval)) return JS_FALSE;
|
||||
/* don't do security here -- we passed the check in file_write */
|
||||
str = JS_NewStringCopyZ(cx, LINEBREAK);
|
||||
count = js_FileWrite(cx, file, JS_GetStringChars(str), JS_GetStringLength(str), file->type);
|
||||
|
||||
if (count==-1){
|
||||
if (js_FileWrite(cx, file, JS_GetStringChars(str), JS_GetStringLength(str), file->type)==-1){
|
||||
/* TODO: error */
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
/* eol causes flush if autoflush is turned on */
|
||||
if (file->autoflush)
|
||||
/* eol causes flush if hasAutoflush is turned on */
|
||||
if (file->hasAutoflush)
|
||||
file_flush(cx, obj, 0, NULL, NULL);
|
||||
|
||||
*rval = JSVAL_TRUE;
|
||||
@ -1877,28 +1920,33 @@ enum file_tinyid {
|
||||
FILE_MODIFIED = -15,
|
||||
FILE_SIZE = -16,
|
||||
FILE_RANDOMACCESS = -17,
|
||||
FILE_POSITION = -18
|
||||
|
||||
FILE_POSITION = -18,
|
||||
FILE_APPEND = -19,
|
||||
FILE_REPLACE = -20,
|
||||
FILE_AUTOFLUSH = -21,
|
||||
};
|
||||
|
||||
static JSPropertySpec file_props[] = {
|
||||
{"length", FILE_LENGTH, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{"parent", FILE_PARENT, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{"path", FILE_PATH, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{"name", FILE_NAME, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{"isDirectory", FILE_ISDIR, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{"isFile", FILE_ISFILE, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{"exists", FILE_EXISTS, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{"canRead", FILE_CANREAD, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{"canWrite", FILE_CANWRITE, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{"isOpen", FILE_OPEN, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{"type", FILE_TYPE, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{"mode", FILE_MODE, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{"creationTime",FILE_CREATED, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{"lastModified",FILE_MODIFIED, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{"size", FILE_SIZE, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{"randomAccess",FILE_RANDOMACCESS, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{"position", FILE_POSITION, JSPROP_ENUMERATE },
|
||||
{"length", FILE_LENGTH, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{"parent", FILE_PARENT, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{"path", FILE_PATH, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{"name", FILE_NAME, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{"isDirectory", FILE_ISDIR, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{"isFile", FILE_ISFILE, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{"exists", FILE_EXISTS, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{"canRead", FILE_CANREAD, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{"canWrite", FILE_CANWRITE, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{"canAppend", FILE_APPEND, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{"canReplace", FILE_REPLACE, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{"isOpen", FILE_OPEN, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{"type", FILE_TYPE, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{"mode", FILE_MODE, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{"creationTime", FILE_CREATED, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{"lastModified", FILE_MODIFIED, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{"size", FILE_SIZE, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{"hasRandomAccess", FILE_RANDOMACCESS, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{"hasAutoflush", FILE_AUTOFLUSH, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{"position", FILE_POSITION, JSPROP_ENUMERATE },
|
||||
{0}
|
||||
};
|
||||
|
||||
@ -1913,7 +1961,6 @@ file_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
||||
PRExplodedTime
|
||||
expandedTime;
|
||||
JSObject *newobj;
|
||||
JSBool flag;
|
||||
|
||||
tiny = JSVAL_TO_INT(id);
|
||||
file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
|
||||
@ -1922,13 +1969,15 @@ file_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
||||
/* SECURITY ??? */
|
||||
switch (tiny) {
|
||||
case FILE_PARENT:
|
||||
if(!isRoot(file->path){
|
||||
str = fileDirectoryName(cx, file->path);
|
||||
str = fileDirectoryName(cx, file->path);
|
||||
/* root.parent = null */
|
||||
if(!strcmp(file->path, str) || !strncmp(str, file->path, strlen(str)-1)){
|
||||
*vp = JSVAL_NULL;
|
||||
}else{
|
||||
newobj = js_NewFileObject(cx, str);
|
||||
JS_free(cx, str);
|
||||
*vp = OBJECT_TO_JSVAL(newobj);
|
||||
}else
|
||||
*vp = JSVAL_NULL;
|
||||
}
|
||||
break;
|
||||
case FILE_PATH:
|
||||
*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, file->path));
|
||||
@ -1955,6 +2004,15 @@ file_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
||||
case FILE_OPEN:
|
||||
*vp = BOOLEAN_TO_JSVAL(file->isOpen);
|
||||
break;
|
||||
case FILE_APPEND :
|
||||
*vp = BOOLEAN_TO_JSVAL((file->mode&PR_APPEND)==PR_APPEND);
|
||||
break;
|
||||
case FILE_REPLACE :
|
||||
*vp = BOOLEAN_TO_JSVAL((file->mode&PR_TRUNCATE)==PR_TRUNCATE);
|
||||
break;
|
||||
case FILE_AUTOFLUSH :
|
||||
*vp = BOOLEAN_TO_JSVAL(file->hasAutoflush);
|
||||
break;
|
||||
case FILE_TYPE:
|
||||
switch (file->type) {
|
||||
case ASCII:
|
||||
@ -1970,8 +2028,8 @@ file_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
||||
; /* time to panic, or to do nothing.. */
|
||||
}
|
||||
break;
|
||||
case FILE_MODE:
|
||||
str = (char*)JS_malloc(cx, 200); /* Big enough to contain all the modes. */
|
||||
/*case FILE_MODE:
|
||||
str = (char*)JS_malloc(cx, 200);
|
||||
str[0] = '\0';
|
||||
flag = JS_FALSE;
|
||||
|
||||
@ -2005,14 +2063,15 @@ file_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
||||
strcat(str, "replace");
|
||||
flag = JS_TRUE;
|
||||
}
|
||||
if (file->autoflush) {
|
||||
if (file->hasAutoflush) {
|
||||
if (flag) strcat(str, ",");
|
||||
strcat(str, "autoflush");
|
||||
strcat(str, "hasAutoflush");
|
||||
flag = JS_TRUE;
|
||||
}
|
||||
*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, str));
|
||||
JS_free(cx, str);
|
||||
break;
|
||||
*/
|
||||
case FILE_CREATED:
|
||||
if(!file->isNative){
|
||||
if(((file->isOpen)?
|
||||
@ -2067,7 +2126,7 @@ file_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
while ((entry = PR_ReadDir(dir, PR_SKIP_BOTH))!=NULL) {
|
||||
while ((entry = PR_ReadDir(dir, PR_SKIP_BOTH))) {
|
||||
count++;
|
||||
}
|
||||
|
||||
@ -2095,7 +2154,7 @@ file_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
||||
|
||||
break;
|
||||
case FILE_RANDOMACCESS:
|
||||
*vp = BOOLEAN_TO_JSVAL(file->randomAccess);
|
||||
*vp = BOOLEAN_TO_JSVAL(file->hasRandomAccess);
|
||||
break;
|
||||
case FILE_POSITION:
|
||||
if (file->isOpen) {
|
||||
@ -2108,7 +2167,6 @@ file_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
||||
}
|
||||
break;
|
||||
default:{
|
||||
char *prop_name = JS_GetStringBytes(JS_ValueToString(cx, id));
|
||||
/* this is some other property -- try to use the dir["file"] syntax */
|
||||
if(js_isDirectory(file)){
|
||||
PRDir *dir = NULL;
|
||||
@ -2117,8 +2175,9 @@ file_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
||||
|
||||
dir = PR_OpenDir(file->path);
|
||||
if(!dir) {
|
||||
/* TODO: error */
|
||||
return JS_FALSE;
|
||||
/* Don't return false, just proceed, this shouldn't happen */
|
||||
JS_ReportWarning(cx, "Can't open directory %s", file->path);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
while((entry = PR_ReadDir(dir, PR_SKIP_NONE))!=NULL){
|
||||
@ -2156,10 +2215,10 @@ file_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
||||
switch (slot) {
|
||||
/* File.position = 10 */
|
||||
case FILE_POSITION:
|
||||
if (file->randomAccess) {
|
||||
if (file->hasRandomAccess) {
|
||||
offset = JSVAL_TO_INT(*vp);
|
||||
count = (!file->isNative)?
|
||||
PR_Seek( file->handle, offset, PR_SEEK_SET):
|
||||
PR_Seek(file->handle, offset, PR_SEEK_SET):
|
||||
fseek(file->nativehandle, offset, SEEK_SET);
|
||||
js_ResetBuffers(file);
|
||||
*vp = INT_TO_JSVAL(count);
|
||||
@ -2258,7 +2317,7 @@ file_init(JSContext *cx, JSObject *obj, char *bytes)
|
||||
|
||||
/* Returns a JSObject */
|
||||
JS_EXPORT_API(JSObject*)
|
||||
js_NewFileObject(JSContext *cx, char *bytes)
|
||||
js_NewFileObject(JSContext *cx, char *filename)
|
||||
{
|
||||
JSObject *obj;
|
||||
JSFile *file;
|
||||
@ -2268,7 +2327,7 @@ js_NewFileObject(JSContext *cx, char *bytes)
|
||||
/* TODO: error ? */
|
||||
return NULL;
|
||||
}
|
||||
file = file_init(cx, obj, bytes);
|
||||
file = file_init(cx, obj, filename);
|
||||
if(!file) return NULL;
|
||||
return obj;
|
||||
}
|
||||
@ -2350,13 +2409,16 @@ js_InitFileClass(JSContext *cx, JSObject* obj)
|
||||
JS_DefinePropertyWithTinyId(cx, ctor, CURRENTDIR_PROPERTY, 0, vp,
|
||||
JS_PropertyStub, file_currentDirSetter, JSPROP_ENUMERATE);
|
||||
|
||||
#ifdef JS_HAS_STANDARD_STREAMS
|
||||
#ifdef JS_FILE_HAS_STANDARD_STREAMS
|
||||
# ifdef XP_MAC
|
||||
# error "Standard streams are not supported on the MAC, turn JS_FILE_HAS_STANDARD_STREAMS off"
|
||||
# else
|
||||
/* Code to create stdin, stdout, and stderr. Insert in the appropriate place. */
|
||||
/* Define input */
|
||||
afile = js_NewFileObjectFromFILE(cx, stdin, SPECIAL_FILE_STRING, JS_TRUE);
|
||||
if (!afile) return NULL;
|
||||
fileObj = JS_GetInstancePrivate(cx, afile, &file_class, NULL);
|
||||
fileObj->randomAccess = JS_FALSE;
|
||||
fileObj->hasRandomAccess = JS_FALSE;
|
||||
vp = OBJECT_TO_JSVAL(afile);
|
||||
JS_SetProperty(cx, ctor, "input", &vp);
|
||||
|
||||
@ -2364,7 +2426,7 @@ js_InitFileClass(JSContext *cx, JSObject* obj)
|
||||
afile = js_NewFileObjectFromFILE(cx, stdout, SPECIAL_FILE_STRING, JS_TRUE);
|
||||
if (!afile) return NULL;
|
||||
fileObj = JS_GetInstancePrivate(cx, afile, &file_class, NULL);
|
||||
fileObj->randomAccess = JS_FALSE;
|
||||
fileObj->hasRandomAccess = JS_FALSE;
|
||||
vp = OBJECT_TO_JSVAL(afile);
|
||||
JS_SetProperty(cx, ctor, "output", &vp);
|
||||
|
||||
@ -2373,9 +2435,10 @@ js_InitFileClass(JSContext *cx, JSObject* obj)
|
||||
if (!afile)
|
||||
return NULL;
|
||||
fileObj = JS_GetInstancePrivate(cx, afile, &file_class, NULL);
|
||||
fileObj->randomAccess = JS_FALSE;
|
||||
fileObj->hasRandomAccess = JS_FALSE;
|
||||
vp = OBJECT_TO_JSVAL(afile);
|
||||
JS_SetProperty(cx, ctor, "error", &vp);
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
#endif /* JS_HAS_FILE_OBJECT */
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user