Check-in [149aa89b7d]
Overview
Comment:Added better error reporting in the core and as part of the ABI
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 149aa89b7d2eb4fceef93f51b11c49ce2fb195ed8774efa5181659637295cc4c
User & Date: rkeene on 2019-09-13 16:02:46
Other Links: manifest | tags
Context
2019-09-13
18:43
First implementation of nearly complete channel driver, marked more TODO and cleaned up whitespace check-in: 38bed7cee0 user: rkeene tags: trunk
16:02
Added better error reporting in the core and as part of the ABI check-in: 149aa89b7d user: rkeene tags: trunk
2019-06-22
22:15
Additional cleanup check-in: aa32555a0a user: rkeene tags: trunk
Changes

Modified xvfs-core.c from [1dde3041c8] to [ca046857f0].

45
46
47
48
49
50
51





















52
53
54
55
56
57
58
	/* XXX:TODO: Should this use the native OS path separator ? */
	if (pathStr[rootLen] != '/') {
		return(NULL);
	}
	
	return(pathStr + rootLen + 1);
}






















/*
 * Internal Tcl_Filesystem functions, with the appropriate instance info
 */
static int xvfs_tclfs_pathInFilesystem(Tcl_Obj *path, ClientData *dataPtr, struct xvfs_tclfs_instance_info *instanceInfo) {
	const char *relativePath;
	







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
	/* XXX:TODO: Should this use the native OS path separator ? */
	if (pathStr[rootLen] != '/') {
		return(NULL);
	}
	
	return(pathStr + rootLen + 1);
}

static const char *xvfs_perror(int xvfs_error) {
	if (xvfs_error >= 0) {
		return("Not an error");
	}

	switch (xvfs_error) {
		case XVFS_RV_ERR_ENOENT:
			return("No such file or directory");
		case XVFS_RV_ERR_EINVAL:
			return("Invalid argument");
		case XVFS_RV_ERR_EISDIR:
			return("Is a directory");
		case XVFS_RV_ERR_ENOTDIR:
			return("Not a directory");
		case XVFS_RV_ERR_EFAULT:
			return("Bad address");
		default:
			return("Unknown error");
	}
}

/*
 * Internal Tcl_Filesystem functions, with the appropriate instance info
 */
static int xvfs_tclfs_pathInFilesystem(Tcl_Obj *path, ClientData *dataPtr, struct xvfs_tclfs_instance_info *instanceInfo) {
	const char *relativePath;
	
67
68
69
70
71
72
73



74
75
76
77
78
79
80
81
82
83


84
85

86
87
88
89
90
91
92
static int xvfs_tclfs_stat(Tcl_Obj *path, Tcl_StatBuf *statBuf, struct xvfs_tclfs_instance_info *instanceInfo) {
	const char *pathStr;
	int retval;

	pathStr = xvfs_relativePath(path, instanceInfo);
	
	retval = instanceInfo->fsInfo->getStatProc(pathStr, statBuf);



	
	return(retval);
}

static Tcl_Obj *xvfs_tclfs_listVolumes(struct xvfs_tclfs_instance_info *instanceInfo) {
	return(NULL);
}

static Tcl_Channel xvfs_tclfs_openFileChannel(Tcl_Interp *interp, Tcl_Obj *path, int mode, int permissions, struct xvfs_tclfs_instance_info *instanceInfo) {
	const char *pathStr;



	pathStr = xvfs_relativePath(path, instanceInfo);

	/*
	 * XXX:TODO: Do something to create the Tcl_Channel we
	 * need to return here
	 */

	return(NULL);
}







>
>
>










>
>


>







88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
static int xvfs_tclfs_stat(Tcl_Obj *path, Tcl_StatBuf *statBuf, struct xvfs_tclfs_instance_info *instanceInfo) {
	const char *pathStr;
	int retval;

	pathStr = xvfs_relativePath(path, instanceInfo);
	
	retval = instanceInfo->fsInfo->getStatProc(pathStr, statBuf);
	if (retval < 0) {
		retval = -1;
	}
	
	return(retval);
}

static Tcl_Obj *xvfs_tclfs_listVolumes(struct xvfs_tclfs_instance_info *instanceInfo) {
	return(NULL);
}

static Tcl_Channel xvfs_tclfs_openFileChannel(Tcl_Interp *interp, Tcl_Obj *path, int mode, int permissions, struct xvfs_tclfs_instance_info *instanceInfo) {
	const char *pathStr;
	Tcl_WideInt length;
	const char *data;

	pathStr = xvfs_relativePath(path, instanceInfo);

	/*
	 * XXX:TODO: Do something to create the Tcl_Channel we
	 * need to return here
	 */

	return(NULL);
}

Modified xvfs-core.h from [689f90a830] to [f98af2d91c].

1
2
3
4
5
6
7
8
9
10
11





12
13
14
15
16
17
18
19










20
21
22
23
24
25
26
#ifndef XVFS_CORE_H_1B4B28D60EBAA11D5FF85642FA7CA22C29E8E817
#define XVFS_CORE_H_1B4B28D60EBAA11D5FF85642FA7CA22C29E8E817 1

#include <tcl.h>

#define XVFS_PROTOCOL_VERSION 1

typedef const char **(*xvfs_proc_getChildren_t)(const char *path, Tcl_WideInt *count);
typedef const unsigned char *(*xvfs_proc_getData_t)(const char *path, Tcl_WideInt start, Tcl_WideInt *length);
typedef int (*xvfs_proc_getStat_t)(const char *path, Tcl_StatBuf *statBuf);






struct Xvfs_FSInfo {
	int                      protocolVersion;
	const char               *name;
	xvfs_proc_getChildren_t  getChildrenProc;
	xvfs_proc_getData_t      getDataProc;
	xvfs_proc_getStat_t      getStatProc;
};











#define XVFS_REGISTER_INTERFACE(name) int name(Tcl_Interp *interp, struct Xvfs_FSInfo *fsInfo);

#if defined(XVFS_MODE_STANDALONE)
/*
 * In standalone mode, we just redefine calls to
 * Xvfs_Register() to go to the xvfs_standalone_register()
 * function











>
>
>
>
>








>
>
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#ifndef XVFS_CORE_H_1B4B28D60EBAA11D5FF85642FA7CA22C29E8E817
#define XVFS_CORE_H_1B4B28D60EBAA11D5FF85642FA7CA22C29E8E817 1

#include <tcl.h>

#define XVFS_PROTOCOL_VERSION 1

typedef const char **(*xvfs_proc_getChildren_t)(const char *path, Tcl_WideInt *count);
typedef const unsigned char *(*xvfs_proc_getData_t)(const char *path, Tcl_WideInt start, Tcl_WideInt *length);
typedef int (*xvfs_proc_getStat_t)(const char *path, Tcl_StatBuf *statBuf);

/*
 * Interface for the filesystem to fill out before registering.
 * The protocolVersion is provided first so that if this
 * needs to change over time it can be appropriately handled.
 */
struct Xvfs_FSInfo {
	int                      protocolVersion;
	const char               *name;
	xvfs_proc_getChildren_t  getChildrenProc;
	xvfs_proc_getData_t      getDataProc;
	xvfs_proc_getStat_t      getStatProc;
};

/*
 * Error codes for various calls.  This is part of the ABI and must
 * not be changed.
 */
#define XVFS_RV_ERR_ENOENT   (-8192)
#define XVFS_RV_ERR_EINVAL   (-8193)
#define XVFS_RV_ERR_EISDIR   (-8194)
#define XVFS_RV_ERR_ENOTDIR  (-8195)
#define XVFS_RV_ERR_EFAULT   (-8196)

#define XVFS_REGISTER_INTERFACE(name) int name(Tcl_Interp *interp, struct Xvfs_FSInfo *fsInfo);

#if defined(XVFS_MODE_STANDALONE)
/*
 * In standalone mode, we just redefine calls to
 * Xvfs_Register() to go to the xvfs_standalone_register()
 * function

Modified xvfs.c.rvt from [c8faacca08] to [79089b8f52].

34
35
36
37
38
39
40


41
42
43
44
45
46
47
	unsigned int pathHash;
	size_t pathLen;
	
	if (path == NULL) {
		return(XVFS_NAME_LOOKUP_ERROR);
	}



	pathLen = strlen(path);
	pathHash = Tcl_ZlibAdler32(0, (const unsigned char *) path, pathLen);
	switch (pathHash) {
<?
	for {set index 0} {$index < [llength $::xvfs::outputFiles]} {incr index} {
		set outputFile [lindex $::xvfs::outputFiles $index]
		set outputFileHash [zlib adler32 $outputFile 0]







>
>







34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
	unsigned int pathHash;
	size_t pathLen;
	
	if (path == NULL) {
		return(XVFS_NAME_LOOKUP_ERROR);
	}

printf("Looking for %s\n", path);

	pathLen = strlen(path);
	pathHash = Tcl_ZlibAdler32(0, (const unsigned char *) path, pathLen);
	switch (pathHash) {
<?
	for {set index 0} {$index < [llength $::xvfs::outputFiles]} {incr index} {
		set outputFile [lindex $::xvfs::outputFiles $index]
		set outputFileHash [zlib adler32 $outputFile 0]
78
79
80
81
82
83
84

85
86
87
88
89
90
91
92
93

94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112

113
114
115
116
117

118
119
120
121
122
123
124
125

126
127
128
129
130
131
132
133
134

135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
	}
	
	/*
	 * Get the inode from the lookup function
	 */
	inode = xvfs_<?= $::xvfs::fsName ?>_nameToIndex(path);
	if (inode == XVFS_NAME_LOOKUP_ERROR) {

		return(NULL);
	}
	
	fileInfo = &xvfs_<?= $::xvfs::fsName ?>_data[inode];

	/*
	 * Ensure this is a directory
	 */
	if (fileInfo->type != XVFS_FILE_TYPE_DIR) {

		return(NULL);
	}
	
	*count = fileInfo->size;
	return(fileInfo->data.dirChildren);
}

static const unsigned char *xvfs_<?= $::xvfs::fsName ?>_getData(const char *path, Tcl_WideInt start, Tcl_WideInt *length) {
	struct xvfs_file_data *fileInfo;
	Tcl_WideInt resultLength;
	long inode;

	/*
	 * Validate input parameters
	 */
	if (start < 0) {
		return(NULL);
	}
	

	if (length == NULL) {
		return(NULL);
	}
	
	if (*length < 0) {

		return(NULL);
	}
	
	/*
	 * Get the inode from the lookup function
	 */
	inode = xvfs_<?= $::xvfs::fsName ?>_nameToIndex(path);
	if (inode == XVFS_NAME_LOOKUP_ERROR) {

		return(NULL);
	}
	
	fileInfo = &xvfs_<?= $::xvfs::fsName ?>_data[inode];

	/*
	 * Ensure this is a file that can be read
	 */
	if (fileInfo->type != XVFS_FILE_TYPE_REG) {

		return(NULL);
	}

	/*
	 * Validate the length
	 */
	if (start > fileInfo->size) {
		*length = -1;
		return(NULL);
	}

	if (*length == 0) {
		resultLength = fileInfo->size - start;
	} else {
		resultLength = MIN(fileInfo->size - start, *length);







>









>















|



>
|




>








>









>







|







80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
	}
	
	/*
	 * Get the inode from the lookup function
	 */
	inode = xvfs_<?= $::xvfs::fsName ?>_nameToIndex(path);
	if (inode == XVFS_NAME_LOOKUP_ERROR) {
		*count = XVFS_RV_ERR_ENOENT;
		return(NULL);
	}
	
	fileInfo = &xvfs_<?= $::xvfs::fsName ?>_data[inode];

	/*
	 * Ensure this is a directory
	 */
	if (fileInfo->type != XVFS_FILE_TYPE_DIR) {
		*count = XVFS_RV_ERR_ENOTDIR;
		return(NULL);
	}
	
	*count = fileInfo->size;
	return(fileInfo->data.dirChildren);
}

static const unsigned char *xvfs_<?= $::xvfs::fsName ?>_getData(const char *path, Tcl_WideInt start, Tcl_WideInt *length) {
	struct xvfs_file_data *fileInfo;
	Tcl_WideInt resultLength;
	long inode;

	/*
	 * Validate input parameters
	 */
	if (length == NULL) {
		return(NULL);
	}
	
	if (start < 0) {
		*length = XVFS_RV_ERR_EINVAL;
		return(NULL);
	}
	
	if (*length < 0) {
		*length = XVFS_RV_ERR_EINVAL;
		return(NULL);
	}
	
	/*
	 * Get the inode from the lookup function
	 */
	inode = xvfs_<?= $::xvfs::fsName ?>_nameToIndex(path);
	if (inode == XVFS_NAME_LOOKUP_ERROR) {
		*length = XVFS_RV_ERR_ENOENT;
		return(NULL);
	}
	
	fileInfo = &xvfs_<?= $::xvfs::fsName ?>_data[inode];

	/*
	 * Ensure this is a file that can be read
	 */
	if (fileInfo->type != XVFS_FILE_TYPE_REG) {
		*length = XVFS_RV_ERR_EISDIR;
		return(NULL);
	}

	/*
	 * Validate the length
	 */
	if (start > fileInfo->size) {
		*length = XVFS_RV_ERR_EFAULT;
		return(NULL);
	}

	if (*length == 0) {
		resultLength = fileInfo->size - start;
	} else {
		resultLength = MIN(fileInfo->size - start, *length);
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
	struct xvfs_file_data *fileInfo;
	long inode;

	/*
	 * Validate input parameters
	 */
	if (!statBuf) {
		return(-1);
	}
	
	/*
	 * Get the inode from the lookup function
	 */
	inode = xvfs_<?= $::xvfs::fsName ?>_nameToIndex(path);
	if (inode == XVFS_NAME_LOOKUP_ERROR) {
		return(-1);
	}
	
	fileInfo = &xvfs_<?= $::xvfs::fsName ?>_data[inode];
	
	statBuf->st_dev   = 0;
	statBuf->st_rdev  = 0;
	statBuf->st_ino   = inode;







|







|







168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
	struct xvfs_file_data *fileInfo;
	long inode;

	/*
	 * Validate input parameters
	 */
	if (!statBuf) {
		return(XVFS_RV_ERR_EINVAL);
	}
	
	/*
	 * Get the inode from the lookup function
	 */
	inode = xvfs_<?= $::xvfs::fsName ?>_nameToIndex(path);
	if (inode == XVFS_NAME_LOOKUP_ERROR) {
		return(XVFS_RV_ERR_ENOENT);
	}
	
	fileInfo = &xvfs_<?= $::xvfs::fsName ?>_data[inode];
	
	statBuf->st_dev   = 0;
	statBuf->st_rdev  = 0;
	statBuf->st_ino   = inode;