1/* 2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6#include <errno.h> 7#include <signal.h> 8#include <stdio.h> 9#include <string.h> 10 11#include "Debug.h" 12 13#include "fuse_api.h" 14#include "fuse_config.h" 15#include "FUSEFileSystem.h" 16 17#include "../RequestThread.h" 18 19 20int 21fuse_main_real(int argc, char* argv[], const struct fuse_operations* op, 22 size_t opSize, void* userData) 23{ 24printf("fuse_main_real(%d, %p, %p, %ld, %p)\n", argc, argv, op, opSize, 25userData); 26 // Note: We use the fuse_*() functions here to initialize and run the 27 // file system, although some of them are merely dummies. 28 29 struct fuse_args args = FUSE_ARGS_INIT(argc, argv); 30 31 int result = 1; 32 33 // create the kernel channel 34 struct fuse_chan* channel = fuse_mount("/dummy", &args); 35 if (channel != NULL) { 36 // create the FUSE handle 37 struct fuse* fuseHandle = fuse_new(channel, &args, op, opSize, 38 userData); 39 if (fuseHandle != NULL) { 40 // run the main loop 41 result = fuse_loop_mt(fuseHandle); 42 43 fuse_destroy(fuseHandle); 44 } 45 46 fuse_unmount("/dummy", channel); 47 } 48 49 fuse_opt_free_args(&args); 50 51 return result; 52} 53 54 55int 56fuse_version(void) 57{ 58 return FUSE_VERSION; 59} 60 61 62struct fuse_context* 63fuse_get_context(void) 64{ 65 RequestThread* requestThread = RequestThread::GetCurrentThread(); 66 return requestThread != NULL 67 ? (fuse_context*)requestThread->GetContext()->GetFSData() 68 : NULL; 69} 70 71 72struct fuse_chan* 73fuse_mount(const char* mountpoint, struct fuse_args* args) 74{ 75 // make sure the stdin/out/err descriptors are open 76 while (true) { 77 int fd = open("/dev/null", O_RDONLY); 78 if (fd < 0) { 79 ERROR(("fuse_mount(): Failed to open /dev/null: %s\n", 80 strerror(errno))); 81 return NULL; 82 } 83 84 if (fd > 2) { 85 close(fd); 86 break; 87 } 88 } 89 90 if (!fuse_parse_mount_config_args(args)) 91 return NULL; 92 93 return (fuse_chan*)FUSEFileSystem::GetInstance(); 94} 95 96 97void 98fuse_unmount(const char* mountpoint, struct fuse_chan* ch) 99{ 100 // nothing to do 101} 102 103 104struct fuse* 105fuse_new(struct fuse_chan* ch, struct fuse_args* args, 106 const struct fuse_operations *op, size_t opSize, void *userData) 107{ 108 // parse args 109 fuse_config config; 110 memset(&config, 0, sizeof(config)); 111 config.entry_timeout = 1.0; 112 config.attr_timeout = 1.0; 113 config.negative_timeout = 0.0; 114 config.intr_signal = SIGUSR1; 115 116 bool success = fuse_parse_lib_config_args(args, &config); 117 118 if (!success) { 119 PRINT(("fuse_new(): failed to parse arguments!\n")); 120 return NULL; 121 } 122 123 // run the main loop 124 status_t error = FUSEFileSystem::GetInstance()->FinishInitClientFS(&config, 125 op, opSize, userData); 126 127 return error == B_OK ? (struct fuse*)FUSEFileSystem::GetInstance() : NULL; 128} 129 130 131struct fuse_session *fuse_lowlevel_new(struct fuse_args *args, 132 const struct fuse_lowlevel_ops *lowLevelOps, size_t lowLevelOpSize, void *userData) 133{ 134 // parse args 135 fuse_config config; 136 memset(&config, 0, sizeof(config)); 137 config.entry_timeout = 1.0; 138 config.attr_timeout = 1.0; 139 config.negative_timeout = 0.0; 140 config.intr_signal = SIGUSR1; 141 142 bool success = fuse_parse_lib_config_args(args, &config); 143 144 if (!success) { 145 PRINT(("fuse_lowlevel_new(): failed to parse arguments!\n")); 146 return NULL; 147 } 148 149 // run the main loop 150 status_t error = FUSEFileSystem::GetInstance()->FinishInitClientFS(&config, 151 lowLevelOps, lowLevelOpSize, userData); 152 153 return error == B_OK ? (struct fuse_session*)FUSEFileSystem::GetInstance() : NULL; 154} 155 156 157void 158fuse_destroy(struct fuse* f) 159{ 160 // TODO: Implement! 161} 162 163 164int 165fuse_loop(struct fuse* f) 166{ 167 status_t error = FUSEFileSystem::GetInstance()->MainLoop(false); 168 return error == B_OK ? 0 : -1; 169} 170 171 172int 173fuse_loop_mt(struct fuse* f) 174{ 175 status_t error = FUSEFileSystem::GetInstance()->MainLoop(true); 176 return error == B_OK ? 0 : -1; 177} 178 179 180int 181fuse_session_loop(struct fuse_session* f) 182{ 183 status_t error = FUSEFileSystem::GetInstance()->MainLoop(false); 184 return error == B_OK ? 0 : -1; 185} 186 187 188int 189fuse_session_loop_mt(struct fuse_session* f) 190{ 191 status_t error = FUSEFileSystem::GetInstance()->MainLoop(true); 192 return error == B_OK ? 0 : -1; 193} 194 195 196void 197fuse_exit(struct fuse* f) 198{ 199 // TODO: Implement! 200} 201 202 203int 204fuse_interrupted(void) 205{ 206 // TODO: ? 207 return false; 208} 209 210 211int 212fuse_invalidate(struct fuse* f, const char* path) 213{ 214 return EINVAL; 215} 216