//Write to a file static int x11fs_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { //Iterate through our layout size_t files_length = sizeof(x11fs_files)/sizeof(struct x11fs_file); for(size_t i=0; i<files_length; i++){ //If our file is in the layout if(!fnmatch(x11fs_files[i].path, path, FNM_PATHNAME)){ //If the path is to a window check it exists int wid; if((wid=get_winid(path)) != -1 && !exists(wid)){ return -ENOENT; } //Check we can actually read if(x11fs_files[i].dir) return -EISDIR; if(!x11fs_files[i].write) return -EACCES; //Call the write function char *trunc_buf = strndup(buf, size); x11fs_files[i].write(wid, trunc_buf); free(trunc_buf); } } return size; }
//Read a file static int x11fs_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { //Iterate through our layout size_t files_length = sizeof(x11fs_files)/sizeof(struct x11fs_file); for(size_t i=0; i<files_length; i++){ //If our file is in the layout if(!fnmatch(x11fs_files[i].path, path, FNM_PATHNAME)){ //If the path is to a window check it exists int wid; if((wid=get_winid(path)) != -1 && !exists(wid)){ return -ENOENT; } //Check we can actually read if(x11fs_files[i].dir) return -EISDIR; if(!x11fs_files[i].read) return -EACCES; //Call the read function and stick the results in the buffer char *result= x11fs_files[i].read(wid); if(!result) return errno; size_t len = strlen(result); if(size > len) size = len; memcpy(buf, result, size); free(result); return size; } } return -ENOENT; }
//Delete a folder (closes a window) static int x11fs_rmdir(const char *path) { //Check the folder is one representing a window //Returning ENOSYS because sometimes this will be on a dir, just not one that represents a window //TODO: Probably return more meaningful errors int wid; if((wid=get_winid(path)) == -1 || strlen(path)>11) return -ENOSYS; //Close the window close_window(wid); return 0; }
//Gives information about a file static int x11fs_getattr(const char *path, struct stat *stbuf) { //zero the information about the file memset(stbuf, 0, sizeof(struct stat)); //loop through our filesystem layout and check if the path matches one in our layout size_t files_length = sizeof(x11fs_files)/sizeof(struct x11fs_file); for(size_t i=0; i<files_length; i++){ if(!fnmatch(x11fs_files[i].path, path, FNM_PATHNAME)){ //if the path is to a window file, check that the window exists int wid; if((wid=get_winid(path)) != -1 && !exists(wid)){ return -ENOENT; } //if a path matches just use the information about the file from the layout stbuf->st_nlink = x11fs_files[i].dir ? 2 : 1; stbuf->st_mode = x11fs_files[i].mode; //Set the size of a file by getting its contents //If the file uses direct IO (it acts like a stream, just set size to 0) stbuf->st_size = 0; if((x11fs_files[i].read != NULL) && !(x11fs_files[i].direct_io)) { char *read_string=x11fs_files[i].read(wid); if(!read_string) return errno; stbuf->st_size=strlen(read_string); free(read_string); } return 0; } } //No such file or directory return -ENOENT; }
//Open a file, just check if it exists and set non seekable static int x11fs_open(const char *path, struct fuse_file_info *fi) { //Iterate through our layout size_t files_length = sizeof(x11fs_files)/sizeof(struct x11fs_file); for(size_t i=0; i<files_length; i++){ //If our file is in the layout if(!fnmatch(x11fs_files[i].path, path, FNM_PATHNAME)){ //If the path is to a window check it exists int wid; if((wid=get_winid(path)) != -1 && !exists(wid)){ return -ENOENT; } //Check if open makes sense if(x11fs_files[i].dir) return -EISDIR; fi->nonseekable=1; fi->direct_io=x11fs_files[i].direct_io; return 0; } } return -ENOENT; }
int main(int argc, char **argv) { char *mpchild; char winid[2]; static const char *job_key = "MP_PARTITION"; static const char *job_win = "MP_MPI_NETWORK"; /* Check that calling args are correct */ if (argc < 4) { fprintf(stderr, "%s: insufficent arguments\n", argv[0]); return 1; } if ((mpchild = getenv("MP_CHILD")) == NULL) { fprintf(stderr, "%s: MP_CHILD not in environment\n", argv[0]); return 1; } /* * Build up job key and window variables and put into environment. * The job key is the first argument. * The switch window_id_file is the second argument. */ if (put_env_var(job_key, argv[1])) { fprintf(stderr, "%s: unable to set environment variable %s\n", argv[0], job_key); return 1; } winid[0] = get_winid(argv[2], mpchild); /* null terminate winid */ winid[1] = '\0'; if (winid[0] == '\0') { fprintf(stderr, "%s: unable to obtain switch window id\n", argv[0]); return 1; } if (put_env_var(job_win, winid)) { fprintf(stderr, "%s: unable to set environment variable %s\n", argv[0], job_win); return 1; } /* now exec the real program with its args */ if (execvp(argv[3], &argv[3]) < 0) { fprintf(stderr, "%s: unable to exec %s\n", argv[0], argv[3]); perror("error:"); return 1; } return 0; }
//Gives the contents of a directory static int x11fs_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) { (void) offset; (void) fi; //If the path is to a non existant window says so int wid; if((wid = get_winid(path)) != -1 && !exists(wid)){ return -ENOENT; } bool exists = false; bool dir = false; //Iterate through our filesystem layout size_t files_length = sizeof(x11fs_files)/sizeof(struct x11fs_file); for(size_t i=0; i<files_length; i++){ //If the path was to a window replace the wildcard in the layout with the actual window we're looking at char *matchpath; if((wid != -1) && (get_winid(x11fs_files[i].path) != -1)){ matchpath=malloc(strlen(x11fs_files[i].path)+8); sprintf(matchpath, "/0x%08x", wid); sprintf(matchpath+11, x11fs_files[i].path+4); } else matchpath=strdup(x11fs_files[i].path); //As the path for the root directory is just a / with no text we need to treat it as being 0 length //This is for when we check if something in our layout is in the folder we're looking at, but not in a subfolder int len = !strcmp(path, "/") ? 0 : strlen(path); //If the file exists in our layout if(!strncmp(path, matchpath, strlen(path))){ exists = true; //Check that to see if an element in our layout is directly below the folder we're looking at in the heirarchy //If so add it to the directory listing if((strlen(matchpath) > strlen(path)) && ((matchpath+len)[0] == '/') && !strchr(matchpath+len+1, '/')){ dir = true; //If it's a wildcarded window in our layout with the list of actual windows if(!strcmp(matchpath, "/0x*")){ //Get the list of windows int *wins = list_windows(); //Add each window to our directory listing for(int j=0; wins[j]; j++){ int win = wins[j]; char *win_string; win_string = malloc(sizeof(char)*(WID_STRING_LENGTH)); sprintf(win_string, "0x%08x", win); filler(buf, win_string, NULL, 0); free(win_string); } free(wins); } //Otherwise just add the file to our directory listing else filler(buf, matchpath+len+1, NULL, 0); } } free(matchpath); } if(!exists) return -ENOENT; //Add any extra needed elements to the directory list if(dir){ filler(buf, ".", NULL, 0); filler(buf, "..", NULL, 0); }else return -ENOTDIR; return 0; }
main(int argc, char **argv) { int len; char *jk; char *mpchild; char winid; static char *job_key = "MP_PARTITION="; static char job_win[15+SWLINELEN] = "MP_MPI_NETWORK="; /* Check that calling args are correct */ if (argc < 4) { fprintf(stderr, "%s: insufficent arguments\n", argv[0]); return 1; } if ((mpchild = getenv("MP_CHILD")) == NULL) { fprintf(stderr, "%s: MP_CHILD not in environment\n", argv[0]); return 1; } /* * Build up job key and window variables and put into environment. * The job key is the first argument. * The switch window_id_file is the second argument. */ len = strlen(argv[1]) + strlen(job_key) + 1; if ((jk = (char *)malloc(len)) == 0) { fprintf(stderr, "%s: cannot allocate memory\n", argv[0]); return 1; } (void)strcpy(jk, job_key); (void)strcat(jk, argv[1]); putenv(jk); winid = get_winid(argv[2], mpchild); if (winid == '\0') { fprintf(stderr, "%s: unable to obtain switch window id\n", argv[0]); return 1; } len = strlen(job_win); job_win[len] = winid; job_win[len+1] = '\0'; putenv(job_win); /* now exec the real program with its args */ if (execvp(argv[3], &argv[3]) < 0) { fprintf(stderr, "%s: unable to exec %s\n", argv[0], argv[3]); perror("error:"); return 1; } return 0; }