︙ | | |
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
-
+
+
-
-
-
+
+
-
-
-
-
-
-
-
|
/*
* Thread Specific Data (TSD) for Tcl Interpreter for the current thread
*/
static pthread_key_t interpKey;
/*
* Data for a given thread (most likely these will become just globable variables soon.)
* Global variables, needed for all threads but only initialized before any
* FUSE threads are created
*/
struct appfs_thread_data {
const char *cachedir;
time_t boottime;
const char *appfs_cachedir;
time_t appfs_boottime;
struct {
int writable;
} options;
};
/* The global thread data (likely to go away) */
struct appfs_thread_data globalThread;
/*
* AppFS Path Type: Describes the type of path a given file is
*/
typedef enum {
APPFS_PATHTYPE_INVALID,
APPFS_PATHTYPE_FILE,
|
︙ | | |
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
-
|
};
/*
* Create a new Tcl interpreter and completely initialize it
*/
static Tcl_Interp *appfs_create_TclInterp(void) {
Tcl_Interp *interp;
const char *cachedir = globalThread.cachedir;
int tcl_ret;
APPFS_DEBUG("Creating new Tcl interpreter for TID = 0x%llx", (unsigned long long) pthread_self());
interp = Tcl_CreateInterp();
if (interp == NULL) {
fprintf(stderr, "Unable to create Tcl Interpreter. Aborting.\n");
|
︙ | | |
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
|
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
|
-
+
|
return(NULL);
}
/*
* Set global variables from C to Tcl
*/
if (Tcl_SetVar(interp, "::appfs::cachedir", cachedir, TCL_GLOBAL_ONLY) == NULL) {
if (Tcl_SetVar(interp, "::appfs::cachedir", appfs_cachedir, TCL_GLOBAL_ONLY) == NULL) {
fprintf(stderr, "Unable to set cache directory. This should never fail.\n");
Tcl_DeleteInterp(interp);
return(NULL);
}
|
︙ | | |
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
|
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
|
-
+
|
case APPFS_PATHTYPE_INVALID:
res = -EIO;
break;
}
if (pathinfo.packaged) {
if (globalThread.options.writable) {
if (0) {
stbuf->st_mode |= 0222;
}
}
return res;
}
|
︙ | | |
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
|
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
|
-
+
|
*/
static int appfs_fuse_opt_cb(void *data, const char *arg, int key, struct fuse_args *outargs) {
static seen_cachedir = 0;
if (key == FUSE_OPT_KEY_NONOPT && seen_cachedir == 0) {
seen_cachedir = 1;
globalThread.cachedir = strdup(arg);
appfs_cachedir = strdup(arg);
return(0);
}
return(1);
}
|
︙ | | |
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
|
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
|
-
+
-
-
+
|
}
argc--;
argv++;
/*
* Set global variables, these should be configuration options.
*/
globalThread.cachedir = APPFS_CACHEDIR;
appfs_cachedir = APPFS_CACHEDIR;
globalThread.options.writable = 1;
/*
* Set global variable for "boot time" to set a time on directories
* that we fake.
*/
globalThread.boottime = time(NULL);
appfs_boottime = time(NULL);
/*
* Register "sha1" and "appfsd" package with libtcl so that any new
* interpreters created (which are done dynamically by FUSE) can have
* the appropriate configuration done automatically.
*/
Tcl_StaticPackage(NULL, "sha1", Sha1_Init, NULL);
|
︙ | | |
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
|
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
|
-
+
|
/*
* Manually specify cache directory, without FUSE callback
* This option only works when not using FUSE, since we
* do not process it with FUSEs option processing.
*/
if (argc >= 2) {
if (strcmp(argv[0], "--cachedir") == 0) {
globalThread.cachedir = strdup(argv[1]);
appfs_cachedir = strdup(argv[1]);
argc -= 2;
argv += 2;
}
}
/*
|
︙ | | |