Ok, so I have been trying to google the heck out of this thing to absolutely no avail and I'm really and truly stuck! The assignment, as posed to the class by my operating systems concepts teacher, was to start work on creating a file system. To begin with, he pointed us to http://sourceforge.net/apps/mediawiki/fuse/index.php?title=Hello_World#Hello_World_example as an example of using FUSE to create and mount a filesystem consisting of the text file 'hello' containing the text "Hello World!". We were to take this as a base and expand to create three additional files. Taking hellofs.c as the starting point, write a file system that has several files:

* the original "/hello"
* another file that has a different name and content
* a third file that is displayable in the directory list but unreadable otherwise
* a fourth file that returns random strings of random length.

As long as I can get it to work making the second file I feel confident that I can get the rest...but I just can't get it to work properly! It will create the file reference in the directory and mount, but I cannot get it to copy the data *into* the file, it's just filled with memory garbage. Any possible help? I have tried it with the method shown below, and also by trying to have two separate sets of fuse_operations passed into fuse_main, but nothing worked!

#define FUSE_USE_VERSION  26

#include <fuse.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>

static const char *hello_str = "Hello World!\n";
static const char *hello_path = "/hello";
static const char *second_path = "/second";
static const char *second_str = "This is the second file! It works!\n";
static const char *third_path = "/third";
static const char *third_str = "This is the third, and you shouldn't be reading this.\n";

static int hello_getattr(const char *path, struct stat *stbuf) {
	int res = 0;
	memset(stbuf, 0, sizeof(struct stat));
	if (strcmp(path, "/") == 0) {
		stbuf->st_mode = S_IFDIR | 0755;
		stbuf->st_nlink = 2;
	} else if (strcmp(path, hello_path) == 0) {
		stbuf->st_mode = S_IFREG | 0666;
		stbuf->st_nlink = 1;
		stbuf->st_size = strlen(hello_str);
	} else if (strcmp(path, second_path) == 0) {
		stbuf->st_mode = S_IFREG | 0666;
		stbuf->st_nlink = 1;
		stbuf->st_size = strlen(second_str);
	} else if (strcmp(path, third_path) == 0) {
		stbuf->st_mode = S_IFREG | 0000;
		stbuf->st_nlink = 1;
		stbuf->st_size = strlen(third_str);
	else
		res = -ENOENT;

	return res;
}

static int hello_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
		off_t offset, struct fuse_file_info *fi) {
	(void) offset;
	(void) fi;

	if (strcmp(path, "/") != 0)
		return -ENOENT;
	filler(buf, ".", NULL, 0);
	filler(buf, "..", NULL, 0);
	filler(buf, hello_path + 1, NULL, 0);
	
	filler(buf, ".", NULL, 0);
	filler(buf, "..", NULL, 0);
	filler(buf, second_path + 1, NULL, 0);

	return 0;
}

static int hello_open(const char *path, struct fuse_file_info *fi) {
	if (strcmp(path, hello_path) != 0)
		return -ENOENT;



	if ((fi->flags & 3) != O_RDONLY)
		return -EACCES;

	return 0;
}

static int hello_read(const char *path, char *buf, size_t size, off_t offset,
		struct fuse_file_info *fi) {
	size_t len;
	(void) fi;
	//if (strcmp(path, hello_path) != 0)
	//	return -ENOENT;


		//buf = hello_path;
		len = strlen(hello_str);
		if (offset < len) {
			if (offset + size > len)
				size = len - offset;
			memcpy(buf, hello_str + offset, size);
		} //else
			//size = 0;

		len = strlen(second_str);
		if (offset < len) {
			if (offset + size > len)
				size = (len) - offset;
			memcpy(buf, second_str + offset, len);
		} else
			size = 0;
	return size;
}

static struct fuse_operations hello_oper = { .getattr = hello_getattr,
		.readdir = hello_readdir, .open = hello_open, .read = hello_read, };

int main(int argc, char *argv[]) {
	return fuse_main(argc, argv, &hello_oper, NULL);
}

Edited 6 Years Ago by Nick Evan: Fixed link

Fixed it all, and just in the nick of time. Turns out really that was needed throwing in a *lot* of else if action. Perfecto!

#define FUSE_USE_VERSION  26

#include <fuse.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>

static const char *hello_str = "Hello World!\n";
static const char *hello_path = "/hello";
static const char *second_path = "/second";
static const char *second_str = "This is the second file! It works!\n";
static const char *third_path = "/third";
static const char *third_str =
		"This is the third, and you shouldn't be reading this.\n";
static const char *fourth_path = "/fourth";
#define fourth_size 20
#define ALPHABET 26

static int hello_getattr(const char *path, struct stat *stbuf) {
	int res = 0;
	memset(stbuf, 0, sizeof(struct stat));
	if (strcmp(path, "/") == 0) {
		stbuf->st_mode = S_IFDIR | 0755;
		stbuf->st_nlink = 2;
	} else if (strcmp(path, hello_path) == 0) {
		stbuf->st_mode = S_IFREG | 0444;
		stbuf->st_nlink = 1;
		stbuf->st_size = strlen(hello_str);
	} else if (strcmp(path, second_path) == 0) {
		stbuf->st_mode = S_IFREG | 0444;
		stbuf->st_nlink = 1;
		stbuf->st_size = strlen(second_str);
	} else if (strcmp(path, third_path) == 0) {
		stbuf->st_mode = S_IFREG | 0000;
		stbuf->st_nlink = 1;
		stbuf->st_size = strlen(third_str);
	} else if (strcmp(path, fourth_path) == 0) {
		stbuf->st_mode = S_IFREG | 0444;
		stbuf->st_nlink = 1;
		stbuf->st_size = fourth_size;
	} else
		res = -ENOENT;

	return res;
}

static int hello_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
		off_t offset, struct fuse_file_info *fi) {
	(void) offset;
	(void) fi;

	if (strcmp(path, "/") != 0)
		return -ENOENT;
	filler(buf, ".", NULL, 0);
	filler(buf, "..", NULL, 0);
	filler(buf, hello_path + 1, NULL, 0);

	filler(buf, second_path + 1, NULL, 0);

	filler(buf, third_path + 1, NULL, 0);

	filler(buf, fourth_path + 1, NULL, 0);
	return 0;
}

static int hello_open(const char *path, struct fuse_file_info *fi) {
	if ((strcmp(path, hello_path) != 0) && (strcmp(path, second_path) != 0)
			&& (strcmp(path, third_path) != 0) && (strcmp(path, fourth_path)
			!= 0)){
		return -ENOENT;
	}

	if ((strcmp(path, hello_path) == 0) || (strcmp(path, second_path) == 0)
			|| (strcmp(path, fourth_path) == 0)) {
		if ((fi->flags & 3) != O_RDONLY)
			return -EACCES;
	} else if (strcmp(path, third_path) == 0) {
		return -EACCES;
	}

	return 0;
}

static int hello_read(const char *path, char *buf, size_t size, off_t offset,
		struct fuse_file_info *fi) {
	size_t len;
	(void) fi;

	if ((strcmp(path, hello_path) != 0) && (strcmp(path, second_path) != 0)
			&& (strcmp(path, third_path) != 0) && (strcmp(path, fourth_path) != 0))
		return -ENOENT;

	if (strcmp(path, hello_path) == 0) {
		len = strlen(hello_str);
		if (offset < len) {
			if (offset + size > len)
				size = len - offset;
			memcpy(buf, hello_str + offset, size);
		} else
			size = 0;
	} else if (strcmp(path, second_path) == 0) {
		len = strlen(second_str);
		if (offset < len) {
			if (offset + size > len)
				size = (len) - offset;
			memcpy(buf, second_str + offset, len);
		} else
			size = 0;
	} else if (strcmp(path, third_path) == 0) {
		len = strlen(third_str);
		if (offset < len) {
			if (offset + size > len)
				size = (len) - offset;
			memcpy(buf, third_str + offset, len);
		} else
			size = 0;
	} else if (strcmp(path, fourth_path) == 0) {
		int i;
		int fourthLen = rand() % fourth_size;
		char *randString;
		randString = malloc(fourthLen * sizeof(char));
		int randChar;
		len = fourthLen;
		for (i = 0; i < len; i++) {
			randChar = rand() % ALPHABET;
			randString[i] = (char) (randChar + 'A');
		}
		randString[len-1] = '\n';
		if (offset < len) {
			if (offset + size > len)
				size = (len) - offset;
			memcpy(buf, randString + offset, len);

			free(randString);
		} else
			size = 0;
	}

	return size;
}

static struct fuse_operations hello_oper = { .getattr = hello_getattr,
		.readdir = hello_readdir, .open = hello_open, .read = hello_read, };

int main(int argc, char *argv[]) {
	return fuse_main(argc, argv, &hello_oper, NULL);
}

Edited 6 Years Ago by zapman2003: n/a

This question has already been answered. Start a new discussion instead.