Send file descriptor of /dev/fuse from vold.
BUG=25755834
Change-Id: Ica8bd336baa74e117be008a6e7ee34e3ffac3769
diff --git a/CommandListener.cpp b/CommandListener.cpp
index 8b02073..c9123b0 100644
--- a/CommandListener.cpp
+++ b/CommandListener.cpp
@@ -15,7 +15,9 @@
*/
#include <stdlib.h>
+#include <sys/mount.h>
#include <sys/socket.h>
+#include <sys/stat.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
@@ -57,6 +59,7 @@
registerCmd(new ObbCmd());
registerCmd(new StorageCmd());
registerCmd(new FstrimCmd());
+ registerCmd(new AppFuseCmd());
}
#if DUMP_ARGS
@@ -619,3 +622,65 @@
(new android::vold::TrimTask(flags))->start();
return sendGenericOkFail(cli, 0);
}
+
+CommandListener::AppFuseCmd::AppFuseCmd() : VoldCommand("appfuse") {}
+
+int CommandListener::AppFuseCmd::runCommand(SocketClient *cli,
+ int argc,
+ char **argv) {
+ if (argc < 2) {
+ cli->sendMsg(
+ ResponseCode::CommandSyntaxError, "Missing argument", false);
+ return 0;
+ }
+
+ const std::string command(argv[1]);
+
+ if (command == "mount" && argc == 4) {
+ const uid_t uid = atoi(argv[2]);
+ const std::string name(argv[3]);
+ const int device_fd = open("/dev/fuse", O_RDWR);
+ if (device_fd < 0) {
+ sendGenericOkFail(cli, device_fd);
+ return 0;
+ }
+
+ // TODO: Create appfuse directory and mount it.
+ const int result = sendFd(cli, device_fd);
+ close(device_fd);
+ return result;
+ }
+
+ return cli->sendMsg(ResponseCode::CommandSyntaxError, nullptr, false);
+}
+
+int CommandListener::AppFuseCmd::sendFd(SocketClient *cli, int fd) {
+ struct iovec data;
+ char dataBuffer[128];
+ char controlBuffer[CMSG_SPACE(sizeof(int))];
+ struct msghdr message;
+
+ // Message.
+ memset(&message, 0, sizeof(struct msghdr));
+ message.msg_iov = &data;
+ message.msg_iovlen = 1;
+ message.msg_control = controlBuffer;
+ message.msg_controllen = CMSG_SPACE(sizeof(int));
+
+ // Data.
+ data.iov_base = dataBuffer;
+ data.iov_len = snprintf(dataBuffer,
+ sizeof(dataBuffer),
+ "200 %d AppFuse command succeeded",
+ cli->getCmdNum()) + 1;
+
+ // Control.
+ struct cmsghdr* const controlMessage = CMSG_FIRSTHDR(&message);
+ memset(controlBuffer, 0, CMSG_SPACE(sizeof(int)));
+ controlMessage->cmsg_level = SOL_SOCKET;
+ controlMessage->cmsg_type = SCM_RIGHTS;
+ controlMessage->cmsg_len = CMSG_LEN(sizeof(int));
+ *((int *) CMSG_DATA(controlMessage)) = fd;
+
+ return TEMP_FAILURE_RETRY(sendmsg(cli->getSocket(), &message, 0));
+}
diff --git a/CommandListener.h b/CommandListener.h
index 6ed099b..aede465 100644
--- a/CommandListener.h
+++ b/CommandListener.h
@@ -73,6 +73,15 @@
virtual ~FstrimCmd() {}
int runCommand(SocketClient *c, int argc, char ** argv);
};
+
+ class AppFuseCmd : public VoldCommand {
+ public:
+ AppFuseCmd();
+ virtual ~AppFuseCmd() {}
+ int runCommand(SocketClient *c, int argc, char ** argv);
+ private:
+ int sendFd(SocketClient *c, int fd);
+ };
};
#endif