Check-in [997a035b20]
Overview
Comment:Ensure that an standalone XVFS client can co-exist with the server implementation
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 997a035b2046809fc393b14d3af8957ddca04d50e9dfa17dd9072a0165e68c36
User & Date: rkeene on 2020-04-17 17:05:39
Other Links: manifest | tags
Context
2020-04-17
17:06
Ensure C linkage as part of the ABI Leaf check-in: 77b31a15c4 user: rkeene tags: trunk
17:05
Ensure that an standalone XVFS client can co-exist with the server implementation check-in: 997a035b20 user: rkeene tags: trunk
2020-04-13
20:50
More tests regarding threads and child interps check-in: 4a6a7916e7 user: rkeene tags: trunk
Changes

Modified Makefile from [442f001684] to [ffd2581258].

72
73
74
75
76
77
78
79


80
81
82
83
84
85
86
test: example-standalone$(LIB_SUFFIX) xvfs$(LIB_SUFFIX) example-client$(LIB_SUFFIX) example-flexible$(LIB_SUFFIX) Makefile
	rm -f __test__.tcl
	echo 'if {[catch { eval $$::env(XVFS_TEST_LOAD_COMMANDS); source $(XVFS_ROOT_MOUNTPOINT)example/main.tcl }]} { puts stderr $$::errorInfo; exit 1 }; exit 0' > __test__.tcl
	@export XVFS_ROOT_MOUNTPOINT; export XVFS_TEST_LOAD_COMMANDS; for XVFS_TEST_LOAD_COMMANDS in \
		'load ./example-standalone$(LIB_SUFFIX) Xvfs_example' \
		'load -global ./xvfs$(LIB_SUFFIX); load ./example-client$(LIB_SUFFIX) Xvfs_example' \
		'load ./xvfs$(LIB_SUFFIX); load ./example-flexible$(LIB_SUFFIX) Xvfs_example' \
		'load ./example-flexible$(LIB_SUFFIX) Xvfs_example'; do \


			echo "[$${XVFS_TEST_LOAD_COMMANDS}] $(GDB) $(TCLSH) __test__.tcl $(TCL_TEST_ARGS)"; \
			$(GDB) $(TCLSH) __test__.tcl $(TCL_TEST_ARGS) || exit 1; \
	done
	rm -f __test__.tcl

do-test: test








|
>
>







72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
test: example-standalone$(LIB_SUFFIX) xvfs$(LIB_SUFFIX) example-client$(LIB_SUFFIX) example-flexible$(LIB_SUFFIX) Makefile
	rm -f __test__.tcl
	echo 'if {[catch { eval $$::env(XVFS_TEST_LOAD_COMMANDS); source $(XVFS_ROOT_MOUNTPOINT)example/main.tcl }]} { puts stderr $$::errorInfo; exit 1 }; exit 0' > __test__.tcl
	@export XVFS_ROOT_MOUNTPOINT; export XVFS_TEST_LOAD_COMMANDS; for XVFS_TEST_LOAD_COMMANDS in \
		'load ./example-standalone$(LIB_SUFFIX) Xvfs_example' \
		'load -global ./xvfs$(LIB_SUFFIX); load ./example-client$(LIB_SUFFIX) Xvfs_example' \
		'load ./xvfs$(LIB_SUFFIX); load ./example-flexible$(LIB_SUFFIX) Xvfs_example' \
		'load ./example-flexible$(LIB_SUFFIX) Xvfs_example' \
		'load ./xvfs$(LIB_SUFFIX); load ./example-standalone$(LIB_SUFFIX) Xvfs_example' \
		'load ./example-standalone$(LIB_SUFFIX) Xvfs_example; load ./xvfs$(LIB_SUFFIX)'; do \
			echo "[$${XVFS_TEST_LOAD_COMMANDS}] $(GDB) $(TCLSH) __test__.tcl $(TCL_TEST_ARGS)"; \
			$(GDB) $(TCLSH) __test__.tcl $(TCL_TEST_ARGS) || exit 1; \
	done
	rm -f __test__.tcl

do-test: test

Modified xvfs-core.c from [514749566d] to [0880d8a507].

23
24
25
26
27
28
29


30
31
32
33
34
35
36

#if defined(XVFS_MODE_FLEXIBLE) || defined(XVFS_MODE_SERVER)
#define XVFS_INTERNAL_SERVER_MAGIC "\xD4\xF3\x05\x96\x25\xCF\xAF\xFE"
#define XVFS_INTERNAL_SERVER_MAGIC_LEN 8

struct xvfs_tclfs_server_info {
	char magic[XVFS_INTERNAL_SERVER_MAGIC_LEN];


	int (*registerProc)(Tcl_Interp *interp, struct Xvfs_FSInfo *fsInfo);
};
#endif /* XVFS_MODE_FLEXIBLE || XVFS_MODE_SERVER */

#if defined(XVFS_MODE_SERVER) || defined(XVFS_MODE_STANDALONE) || defined(XVFS_MODE_FLEXIBLE)
#ifndef XVFS_ROOT_MOUNTPOINT
#  define XVFS_ROOT_MOUNTPOINT "//xvfs:/"







>
>







23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

#if defined(XVFS_MODE_FLEXIBLE) || defined(XVFS_MODE_SERVER)
#define XVFS_INTERNAL_SERVER_MAGIC "\xD4\xF3\x05\x96\x25\xCF\xAF\xFE"
#define XVFS_INTERNAL_SERVER_MAGIC_LEN 8

struct xvfs_tclfs_server_info {
	char magic[XVFS_INTERNAL_SERVER_MAGIC_LEN];
	int protocolVersion;
	const char *rootMountpoint;
	int (*registerProc)(Tcl_Interp *interp, struct Xvfs_FSInfo *fsInfo);
};
#endif /* XVFS_MODE_FLEXIBLE || XVFS_MODE_SERVER */

#if defined(XVFS_MODE_SERVER) || defined(XVFS_MODE_STANDALONE) || defined(XVFS_MODE_FLEXIBLE)
#ifndef XVFS_ROOT_MOUNTPOINT
#  define XVFS_ROOT_MOUNTPOINT "//xvfs:/"
978
979
980
981
982
983
984




985





986








987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
	fsHandlerData = (struct xvfs_tclfs_server_info *) fsHandlerDataRaw;

	/*
	 * XXX:TODO: What is the chance that the handler for //xvfs:/ hold
	 * client data smaller than XVFS_INTERNAL_SERVER_MAGIC_LEN ?
	 */
	if (memcmp(fsHandlerData->magic, XVFS_INTERNAL_SERVER_MAGIC, sizeof(fsHandlerData->magic)) == 0) {




		XVFS_DEBUG_PUTS("Found a server handler");





		xvfs_register = fsHandlerData->registerProc;








	}

	XVFS_DEBUG_LEAVE;

	return(xvfs_register(interp, fsInfo));
}
#endif /* XVFS_MODE_FLEXIBLE */

#if defined(XVFS_MODE_SERVER)
static Tcl_Filesystem xvfs_tclfs_dispatch_fs;
static Tcl_HashTable xvfs_tclfs_dispatch_map;
static struct xvfs_tclfs_server_info xvfs_tclfs_dispatch_fsdata;

static int xvfs_tclfs_dispatch_pathInFS(Tcl_Obj *path, ClientData *dataPtr) {
	const char *pathStr, *rootStr;
	int pathLen, rootLen;

	XVFS_DEBUG_ENTER;

	XVFS_DEBUG_PRINTF("Verifying that \"%s\" belongs in XVFS ...", Tcl_GetString(path));








>
>
>
>
|
>
>
>
>
>
|
>
>
>
>
>
>
>
>













|







980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
	fsHandlerData = (struct xvfs_tclfs_server_info *) fsHandlerDataRaw;

	/*
	 * XXX:TODO: What is the chance that the handler for //xvfs:/ hold
	 * client data smaller than XVFS_INTERNAL_SERVER_MAGIC_LEN ?
	 */
	if (memcmp(fsHandlerData->magic, XVFS_INTERNAL_SERVER_MAGIC, sizeof(fsHandlerData->magic)) == 0) {
		/*
		 * Refuse to talk to the in-core implementation if it is a lower
		 * version.
		 */
		XVFS_DEBUG_PUTS("Found a server handler, checking for compatible version");
		if (fsHandlerData->protocolVersion >= XVFS_PROTOCOL_VERSION) {
			XVFS_DEBUG_PUTS("Found a server handler with a compatible version, checking for compatible root");
			if (strcmp(XVFS_ROOT_MOUNTPOINT, fsHandlerData->rootMountpoint) == 0) {
				XVFS_DEBUG_PUTS("Found a server handler with a compatible version and checking for compatible root");

				xvfs_register = fsHandlerData->registerProc;
			}
		}
	}

	if (xvfs_register == &xvfs_standalone_register) {
		XVFS_DEBUG_PUTS("Using xvfs_standalone_register");
	} else {
		XVFS_DEBUG_PUTS("Using Xvfs_Register from Xvfs Server Core");
	}

	XVFS_DEBUG_LEAVE;

	return(xvfs_register(interp, fsInfo));
}
#endif /* XVFS_MODE_FLEXIBLE */

#if defined(XVFS_MODE_SERVER)
static Tcl_Filesystem xvfs_tclfs_dispatch_fs;
static Tcl_HashTable xvfs_tclfs_dispatch_map;
static struct xvfs_tclfs_server_info xvfs_tclfs_dispatch_fsdata;

static int xvfs_tclfs_dispatch_pathInXVFS(Tcl_Obj *path) {
	const char *pathStr, *rootStr;
	int pathLen, rootLen;

	XVFS_DEBUG_ENTER;

	XVFS_DEBUG_PRINTF("Verifying that \"%s\" belongs in XVFS ...", Tcl_GetString(path));

1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
	int rootLen;
	char *pathStr, *fsName, *fsNameEnds, origSep;

	XVFS_DEBUG_ENTER;

	path = xvfs_absolutePath(path);

	if (xvfs_tclfs_dispatch_pathInFS(path, NULL) != TCL_OK) {
		Tcl_DecrRefCount(path);

		XVFS_DEBUG_LEAVE;

		return(NULL);
	}








|







1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
	int rootLen;
	char *pathStr, *fsName, *fsNameEnds, origSep;

	XVFS_DEBUG_ENTER;

	path = xvfs_absolutePath(path);

	if (xvfs_tclfs_dispatch_pathInXVFS(path) != TCL_OK) {
		Tcl_DecrRefCount(path);

		XVFS_DEBUG_LEAVE;

		return(NULL);
	}

1091
1092
1093
1094
1095
1096
1097











1098
1099
1100
1101
1102
1103
1104
	 * UNREACH: We do no need the more specific check because we
	 * claim everything under the root, but we want to suppress
	 * a warning about it not being used.
	 */
	xvfs_tclfs_pathInFilesystem(NULL, NULL, NULL);
	return(NULL);
}












static int xvfs_tclfs_dispatch_stat(Tcl_Obj *path, Tcl_StatBuf *statBuf) {
	struct xvfs_tclfs_instance_info *instanceInfo;

	instanceInfo = xvfs_tclfs_dispatch_pathToInfo(path);
	if (!instanceInfo) {
		Tcl_SetErrno(xvfs_errorToErrno(XVFS_RV_ERR_ENOENT));







>
>
>
>
>
>
>
>
>
>
>







1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
	 * UNREACH: We do no need the more specific check because we
	 * claim everything under the root, but we want to suppress
	 * a warning about it not being used.
	 */
	xvfs_tclfs_pathInFilesystem(NULL, NULL, NULL);
	return(NULL);
}

static int xvfs_tclfs_dispatch_pathInFS(Tcl_Obj *path, ClientData *dataPtr) {
	struct xvfs_tclfs_instance_info *instanceInfo;

	instanceInfo = xvfs_tclfs_dispatch_pathToInfo(path);
	if (!instanceInfo) {
		return(-1);
	}

	return(TCL_OK);
}

static int xvfs_tclfs_dispatch_stat(Tcl_Obj *path, Tcl_StatBuf *statBuf) {
	struct xvfs_tclfs_instance_info *instanceInfo;

	instanceInfo = xvfs_tclfs_dispatch_pathToInfo(path);
	if (!instanceInfo) {
		Tcl_SetErrno(xvfs_errorToErrno(XVFS_RV_ERR_ENOENT));
1192
1193
1194
1195
1196
1197
1198
1199


1200
1201
1202
1203
1204
1205
1206
	xvfs_tclfs_dispatch_fs.copyDirectoryProc          = NULL;
	xvfs_tclfs_dispatch_fs.lstatProc                  = NULL;
	xvfs_tclfs_dispatch_fs.loadFileProc               = NULL;
	xvfs_tclfs_dispatch_fs.getCwdProc                 = NULL;
	xvfs_tclfs_dispatch_fs.chdirProc                  = NULL;

	memcpy(xvfs_tclfs_dispatch_fsdata.magic, XVFS_INTERNAL_SERVER_MAGIC, XVFS_INTERNAL_SERVER_MAGIC_LEN);
	xvfs_tclfs_dispatch_fsdata.registerProc = Xvfs_Register;



	tclRet = Tcl_FSRegister((ClientData) &xvfs_tclfs_dispatch_fsdata, &xvfs_tclfs_dispatch_fs);
	if (tclRet != TCL_OK) {
		if (interp) {
			Tcl_SetResult(interp, "Tcl_FSRegister() failed", NULL);
		}








|
>
>







1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
	xvfs_tclfs_dispatch_fs.copyDirectoryProc          = NULL;
	xvfs_tclfs_dispatch_fs.lstatProc                  = NULL;
	xvfs_tclfs_dispatch_fs.loadFileProc               = NULL;
	xvfs_tclfs_dispatch_fs.getCwdProc                 = NULL;
	xvfs_tclfs_dispatch_fs.chdirProc                  = NULL;

	memcpy(xvfs_tclfs_dispatch_fsdata.magic, XVFS_INTERNAL_SERVER_MAGIC, XVFS_INTERNAL_SERVER_MAGIC_LEN);
	xvfs_tclfs_dispatch_fsdata.registerProc    = Xvfs_Register;
	xvfs_tclfs_dispatch_fsdata.protocolVersion = XVFS_PROTOCOL_VERSION;
	xvfs_tclfs_dispatch_fsdata.rootMountpoint  = XVFS_ROOT_MOUNTPOINT;

	tclRet = Tcl_FSRegister((ClientData) &xvfs_tclfs_dispatch_fsdata, &xvfs_tclfs_dispatch_fs);
	if (tclRet != TCL_OK) {
		if (interp) {
			Tcl_SetResult(interp, "Tcl_FSRegister() failed", NULL);
		}