Diff

Differences From Artifact [4a8cebc0f0]:

To Artifact [3133466dff]:


   305    305   
   306    306   		Tcl_DeleteInterp(interp);
   307    307   
   308    308   		interp = NULL;
   309    309   
   310    310   		pthread_ret = pthread_setspecific(interpKey, interp);
   311    311   	}
          312  +
          313  +	if (global_interp_reset_key == -1) {
          314  +		APPFS_DEBUG("Not creating a new interpreter since we are terminating.");
          315  +
          316  +		return(NULL);
          317  +	}
   312    318   
   313    319   	thread_interp_reset_key = global_interp_reset_key;
   314    320   
   315    321   	if (interp == NULL) {
   316    322   		interp = appfs_create_TclInterp(NULL);
   317    323   
   318    324   		if (interp == NULL) {
................................................................................
   344    350   	int i;
   345    351   
   346    352   	if (interp == NULL) {
   347    353   		return(TCL_ERROR);
   348    354   	}
   349    355   
   350    356   	objv = (void *) ckalloc(sizeof(*objv) * objc);
          357  +
   351    358   	objv[0] = Tcl_NewStringObj(cmd, -1);
          359  +
   352    360   	Tcl_IncrRefCount(objv[0]);
   353    361   
   354    362   	va_start(argp, cmd);
   355    363   	for (i = 1; i < objc; i++) {
   356    364   		arg = va_arg(argp, const char *);
          365  +
   357    366   		objv[i] = Tcl_NewStringObj(arg, -1);
          367  +
   358    368   		Tcl_IncrRefCount(objv[i]);
   359    369   	}
   360    370   	va_end(argp);
   361    371   
   362    372   	retval = Tcl_EvalObjv(interp, objc, objv, 0);
   363    373   
   364    374   	for (i = 0; i < objc; i++) {
................................................................................
   756    766   	}
   757    767   
   758    768   	pathinfo->packaged = 0;
   759    769   	pathinfo->inode = appfs_get_path_inode(path);
   760    770   
   761    771   	attr_value_str = Tcl_GetString(attr_value);
   762    772   
   763         -	Tcl_DecrRefCount(attr_value);
   764         -
   765    773   	switch (attr_value_str[0]) {
   766    774   		case 'd': /* directory */
   767    775   			pathinfo->type = APPFS_PATHTYPE_DIRECTORY;
   768    776   			pathinfo->typeinfo.dir.childcount = 0;
   769    777   
   770    778   			Tcl_DictObjGet(interp, attrs_dict, attr_key_childcount, &attr_value);
   771    779   			if (attr_value != NULL) {
   772    780   				tcl_ret = Tcl_GetWideIntFromObj(NULL, attr_value, &attr_value_wide);
   773    781   				if (tcl_ret == TCL_OK) {
   774    782   					pathinfo->typeinfo.dir.childcount = attr_value_wide;
   775    783   				}
   776         -
   777         -				Tcl_DecrRefCount(attr_value);
   778    784   			}
   779    785   
   780    786   			break;
   781    787   		case 'f': /* file */
   782    788   			pathinfo->type = APPFS_PATHTYPE_FILE;
   783    789   			pathinfo->typeinfo.file.size = 0;
   784    790   			pathinfo->typeinfo.file.executable = 0;
................................................................................
   785    791   
   786    792   			Tcl_DictObjGet(interp, attrs_dict, attr_key_size, &attr_value);
   787    793   			if (attr_value != NULL) {
   788    794   				tcl_ret = Tcl_GetWideIntFromObj(NULL, attr_value, &attr_value_wide);
   789    795   				if (tcl_ret == TCL_OK) {
   790    796   					pathinfo->typeinfo.file.size = attr_value_wide;
   791    797   				}
   792         -
   793         -				Tcl_DecrRefCount(attr_value);
   794    798   			}
   795    799   
   796    800   			Tcl_DictObjGet(interp, attrs_dict, attr_key_perms, &attr_value);
   797    801   			if (attr_value != NULL) {
   798    802   				attr_value_str = Tcl_GetString(attr_value);
   799    803   				if (attr_value_str[0] == 'x') {
   800    804   					pathinfo->typeinfo.file.executable = 1;
   801    805   				}
   802         -
   803         -				Tcl_DecrRefCount(attr_value);
   804    806   			}
   805    807   			break;
   806    808   		case 's': /* symlink */
   807    809   			pathinfo->type = APPFS_PATHTYPE_SYMLINK;
   808    810   			pathinfo->typeinfo.symlink.size = 0;
   809    811   			pathinfo->typeinfo.symlink.source[0] = '\0';
   810    812   
................................................................................
   814    816   
   815    817   				if ((attr_value_int + 1) <= sizeof(pathinfo->typeinfo.symlink.source)) {
   816    818   					pathinfo->typeinfo.symlink.size = attr_value_int;
   817    819   					pathinfo->typeinfo.symlink.source[attr_value_int] = '\0';
   818    820   
   819    821   					memcpy(pathinfo->typeinfo.symlink.source, attr_value_str, attr_value_int);
   820    822   				}
   821         -
   822         -				Tcl_DecrRefCount(attr_value);
   823    823   			}
   824    824   			break;
   825    825   		case 'F': /* pipe/fifo */
   826    826   			pathinfo->type = APPFS_PATHTYPE_FIFO;
   827    827   			break;
   828    828   		case 'S': /* UNIX domain socket */
   829    829   			pathinfo->type = APPFS_PATHTYPE_SOCKET;
   830    830   			break;
   831    831   		default:
   832         -			Tcl_DecrRefCount(attrs_dict);
   833         -
   834    832   			Tcl_Release(interp);
   835    833   
   836    834   			return(-EIO);
   837    835   	}
   838    836   
   839    837   	Tcl_DictObjGet(interp, attrs_dict, attr_key_packaged, &attr_value);
   840    838   	if (attr_value != NULL) {
   841    839   		pathinfo->packaged = 1;
   842         -
   843         -		Tcl_DecrRefCount(attr_value);
   844    840   	}
   845    841   
   846    842   	Tcl_DictObjGet(interp, attrs_dict, attr_key_time, &attr_value);
   847    843   	if (attr_value != NULL) {
   848    844   		tcl_ret = Tcl_GetWideIntFromObj(NULL, attr_value, &attr_value_wide);
   849    845   		if (tcl_ret == TCL_OK) {
   850    846   			pathinfo->time = attr_value_wide;
   851    847   		}
   852         -
   853         -		Tcl_DecrRefCount(attr_value);
   854    848   	} else {
   855    849   		pathinfo->time = 0;
   856    850   	}
   857    851   
   858    852   	Tcl_Release(interp);
   859    853   
   860    854   	appfs_get_path_info_cache_add(path, fsuid, pathinfo);
................................................................................
   923    917   
   924    918   	if (real_path == NULL) {
   925    919   		return(NULL);
   926    920   	}
   927    921   
   928    922   	return(strdup(real_path));
   929    923   }
          924  +
          925  +#ifdef APPFS_EXIT_PATH
          926  +static void appfs_exit(void) {
          927  +	int global_interp_reset_key;
          928  +
          929  +	global_interp_reset_key = __sync_fetch_and_add(&interp_reset_key, 0);
          930  +	__sync_fetch_and_sub(&interp_reset_key, global_interp_reset_key);
          931  +
          932  +	while (__sync_sub_and_fetch(&interp_reset_key, 1) >= 0) {
          933  +		/* Busy Loop */
          934  +	}
          935  +
          936  +	global_interp_reset_key = __sync_fetch_and_add(&interp_reset_key, 0);
          937  +	if (global_interp_reset_key != -1) {
          938  +		APPFS_DEBUG("Error sending kill signal to all threads, aborting anyway.");
          939  +	}
          940  +
          941  +	fuse_exit(fuse_get_context()->fuse);
          942  +
          943  +	appfs_get_path_info_cache_flush(-1, -1);
          944  +
          945  +	return;
          946  +}
          947  +#endif
   930    948   
   931    949   static int appfs_fuse_readlink(const char *path, char *buf, size_t size) {
   932    950   	struct appfs_pathinfo pathinfo;
   933    951   	int retval = 0;
   934    952   
   935    953   	APPFS_DEBUG("Enter (path = %s, ...)", path);
   936    954   
................................................................................
   957    975   static int appfs_fuse_getattr(const char *path, struct stat *stbuf) {
   958    976   	struct appfs_pathinfo pathinfo;
   959    977   	int retval;
   960    978   
   961    979   	retval = 0;
   962    980   
   963    981   	APPFS_DEBUG("Enter (path = %s, ...)", path);
          982  +
          983  +#if (defined(DEBUG) && defined(APPFS_EXIT_PATH)) || defined(APPFS_EXIT_PATH_ENABLE_MAJOR_SECURITY_HOLE)
          984  +	/*
          985  +	 * This is a major security issue so we cannot let it be compiled into
          986  +	 * any release
          987  +	 */
          988  +
          989  +	if (strcmp(path, "/exit") == 0) {
          990  +		appfs_exit();
          991  +	}
          992  +#endif
   964    993   
   965    994   	pathinfo.type = APPFS_PATHTYPE_INVALID;
   966    995   
   967    996   	retval = appfs_get_path_info(path, &pathinfo);
   968    997   	if (retval != 0) {
   969    998   		return(retval);
   970    999   	}
................................................................................
  1064   1093   		return(0);
  1065   1094   	}
  1066   1095   
  1067   1096   	for (idx = 0; idx < children_count; idx++) {
  1068   1097   		filler(buf, Tcl_GetString(children[idx]), NULL, 0);
  1069   1098   	}
  1070   1099   
  1071         -	Tcl_DecrRefCount(children);
  1072         -
  1073   1100   	Tcl_Release(interp);
  1074   1101   
  1075   1102   	return(0);
  1076   1103   }
  1077   1104   
  1078   1105   static int appfs_fuse_open(const char *path, struct fuse_file_info *fi) {
  1079   1106   	Tcl_Interp *interp;