Subversion Repositories HelenOS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /** @addtogroup FileLib
  2.  * @{
  3.  */
  4.  
  5. /**
  6.  * @file    file.c
  7.  * @brief   The user library for working with the file system
  8.  */
  9.  
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <unistd.h>
  14. #include <async.h>
  15. #include <ipc/services.h>
  16. #include <ipc/ipc.h>
  17. #include <sys/mman.h>
  18. #include <io/file.h>
  19. #include <bool.h>
  20. #include <err.h>
  21. #include <align.h>
  22. #include "../../../fs/dir.h"
  23. #include "../../../share/message.h"
  24. #include "../../../share/shared_proto.h"
  25.  
  26. #define CONNECT_SLEEP_INTERVAL 10000
  27. #define CONNECT_SLEEP_TIMEOUT 100000
  28. #define CON_FS_ATTEMPTS 1000
  29.  
  30. /**
  31. *
  32. */
  33. static int fs_phone;
  34.  
  35. file_t * file_connect();
  36. int file_disconnect(file_t * file);
  37.  
  38. /**
  39. * Connect to the FS task and share memory with it for further data and
  40. * extended memory transfers
  41. */
  42. file_t * file_connect() {
  43.     file_t * result;   
  44.    
  45.     size_t size;
  46.     void *share = NULL;
  47.     int retval;
  48.  
  49.     printf("Connecting to the SERVICE_FS...");
  50.     if (!connect_to_fs(&fs_phone, CON_FS_ATTEMPTS)) {
  51.         printf("Connection to SERVICE_FS was refused\n");
  52.         f_err = F_IPC_FAILURE;
  53.         return NULL;
  54.     }
  55.     printf("OK\n");
  56.     return F_OK;
  57.    
  58.     printf("Creating address space area...");
  59.     size = ALIGN_UP(BLOCK_SIZE * sizeof(char), PAGE_SIZE);
  60.     share = mmap(share, size, AS_AREA_READ | AS_AREA_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0);
  61.     if ((int)share < 0){
  62.         printf("As_area_create error: %d\n", (int)share);
  63.         f_err = F_MMAP_FAILURE;
  64.         return NULL;
  65.     }
  66.     printf("OK\n");
  67.  
  68.     printf("Connecting the task to FS...");
  69.     retval = async_req_2(fs_phone, FS_NEW_CONSUMER, task_get_id(), 0, NULL, NULL);
  70.     if (retval < 0) {
  71.         printf("FS_NEW_CONSUMER error: %d\n", retval);
  72.         f_err = F_COMM_FAILURE;
  73.         return NULL;
  74.     }
  75.     printf("OK\n");
  76.  
  77.     printf("Sending memory to FS_SERVICE...");
  78.     int flags = 0;
  79.     flags = AS_AREA_READ | AS_AREA_WRITE;
  80.     retval = async_req_3(fs_phone, IPC_M_AS_AREA_SEND, (uintptr_t)share, size, flags, NULL, NULL, NULL);
  81.     if (retval < 0) {
  82.         printf("%d\n", retval);
  83.         f_err = F_COMM_FAILURE;
  84.         return NULL;
  85.     }
  86.     printf("OK\n");
  87.    
  88.     /* Allocating structure for extended message. */
  89.     message_params_t *params;
  90.     params = malloc(sizeof(message_params_t));
  91.     memset((void*)params, 0, sizeof(message_params_t));
  92.    
  93.     result = malloc(sizeof(file_t));
  94.     result->share = share;
  95.     result->size = size;
  96.     result->params = params;
  97.    
  98.     f_err = F_OK;
  99.     return result;
  100. }
  101.  
  102. /**
  103. * Disconnect from the FS task, unsharing memory and freeing the file data structure
  104. */
  105. int file_disconnect(file_t * file) {
  106.     int retval;
  107.    
  108.     printf("Request for dropping the connection to the FS...");
  109.     retval = send_request(fs_phone, FS_DROP_CONSUMER, file->params, file->share);
  110.     if (retval < 0) {
  111.         printf("%d\n", retval);
  112.         return -1;
  113.     }
  114.     printf("OK\n");
  115.    
  116.     /* Unmapping share area. */
  117.     printf("Unmapping share area...");
  118.     retval = munmap(file->share, file->size);
  119.     if (retval < 0) {
  120.         printf("%d\n", retval);
  121.         return -1;
  122.     }
  123.     printf("OK\n");
  124.    
  125.     printf("Creating address space area...");
  126.     file->size = ALIGN_UP(BLOCK_SIZE * sizeof(char), PAGE_SIZE);
  127.     file->share = mmap(file->share, file->size, AS_AREA_READ | AS_AREA_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0);
  128.     if ((int)(file->share) < 0){
  129.         printf("As_area_create error: %d\n", (int)(file->share));
  130.         return -1;
  131.     }
  132.     printf("OK\n");
  133.  
  134.     free(file);
  135.     f_err = F_OK;
  136.     return F_OK;
  137. }
  138.  
  139. /**
  140. * List contents of the current directory
  141. */
  142. dir_item_t * ls(unsigned int * length) {
  143.     dir_item_t * result;
  144.     unsigned short entries_num;
  145.     int retval;
  146.  
  147.     file_t * shared_file = file_connect();
  148.     if (shared_file == NULL) {
  149.         return NULL;
  150.     }
  151.    
  152.     /* We want lookup our work directory. */
  153.     printf("Request for get number of entries...");
  154.     retval = send_request(fs_phone, FS_DSUM, shared_file->params, shared_file->share);
  155.     if (retval < 0) {
  156.         printf("%d\n", retval);
  157.         f_err = F_READ_ERROR;
  158.         return NULL;
  159.     }
  160.     printf("OK\n");
  161.     printf("Total number of entries: %d\n", retval);
  162.    
  163.     entries_num = retval;
  164.     *length = entries_num;
  165.    
  166.     /* File list in working directory. */
  167.     printf("File list:\n");
  168.    
  169.     result = malloc(entries_num * sizeof (dir_item_t));
  170.    
  171.     int entry;
  172.     for (entry = 0; entry < entries_num; entry++) {
  173.  
  174.         shared_file->params->entry_number = entry;
  175.         retval = send_request(fs_phone, FS_READENTRY, shared_file->params, shared_file->share);
  176.         if (retval < 0) {
  177.             printf("%d\n", retval);
  178.             f_err = F_READ_ERROR;
  179.             return NULL;
  180.         }
  181.        
  182.         memcpy(&(result[entry].inode_num), shared_file->share, sizeof(unsigned short));
  183.         memcpy(result[entry].name, (void *)(shared_file->share+sizeof(unsigned short)), retval-sizeof(unsigned short));
  184.  
  185.         /* Do not show empty entries. */
  186.         if (!result[entry].inode_num)
  187.             continue;
  188.          
  189.         printf("Inode number: %u\t\t", result[entry].inode_num);
  190.         printf("File name: %s\n", result[entry].name);
  191.        
  192.     }
  193.     printf("OK\n");
  194.     return result;
  195. }
  196.  
  197. /**
  198. * Change the current working directory for the task
  199. */
  200. int chdir(char * new_dir) {
  201.     int retval;
  202.     file_t * shared_file = file_connect();
  203.    
  204.     if (shared_file == NULL) {
  205.         f_err = F_READ_ERROR;
  206.         return F_READ_ERROR;
  207.     }
  208.     memcpy(shared_file->params->fname, new_dir, 30);
  209.    
  210.     printf("Request for changing the curret directory to %s...", new_dir);
  211.     retval = send_request(fs_phone, FS_CHDIR, shared_file->params, shared_file->share);
  212.     if (retval < 0) {
  213.         printf("%d\n", retval);
  214.         f_err = F_READ_ERROR;
  215.         return F_READ_ERROR;
  216.     }
  217.     printf("OK\n");
  218.  
  219.     retval = file_disconnect(shared_file);
  220.     f_err = F_OK;
  221.     return F_OK;
  222. }
  223.  
  224. /**
  225. * Open a file for reading and/or writing
  226. */
  227. file_t * fopen (char * name, int mode){
  228.     int retval;
  229.     file_t * file = file_connect();
  230.    
  231.     /* We want to work with the specified file. */ 
  232.     memcpy(file->params->fname, name, 30);
  233.  
  234.     printf("Request for opening file %s...", name);
  235.     retval = send_request(fs_phone, FS_OPEN, file->params, file->share);
  236.     if (retval < 0) {
  237.         printf("%d\n", retval);
  238.         return NULL;
  239.     }
  240.     printf("OK\n");
  241.  
  242.     file->handle = retval;
  243.     printf("Returned file handle...%d\n", file->handle);
  244.    
  245.     return file;
  246. }
  247.  
  248. /**
  249. * Read status information about a file
  250. */
  251. int fstat(file_t * file) {
  252.     int retval;
  253.     memcpy(file->params->fname, file->base_info.name, 30);
  254.     file->params->fd = file->handle;
  255.  
  256.     printf("Request for getting info about file %s[FSTAT called]...", file->params->fname);
  257.     retval = send_request(fs_phone, FS_FSTAT, file->params, file->share);
  258.     if (retval < 0) {
  259.         printf("%d\n", retval);
  260.         return -1;
  261.     }
  262.    
  263.     memcpy((void *)(&file->stat), file->share, sizeof(stat_t));
  264.  
  265.     printf("Info about file: %s\n", file->params->fname);
  266.     printf("Inode number: %d\n", file->stat.st_ino);
  267.     printf("Mode: %d\n", file->stat.st_mode);
  268.     printf("Links: %d\n", file->stat.st_nlink);
  269.     printf("Size: %d\n", file->stat.st_size);
  270.    
  271.     printf("OK\n");
  272.    
  273.     f_err = F_OK;
  274.     return F_OK;
  275. }
  276.  
  277. /**
  278. * Read data from a file
  279. */
  280. int fread(file_t * file, void* buffer, unsigned int size){
  281.     int retval;
  282.     file->params->nbytes = size;
  283.    
  284.     printf("Request for reading %d bytes from file %s...", file->params->nbytes, file->params->fname);
  285.     retval = send_request(fs_phone, FS_READ, file->params, file->share);
  286.     if (retval < 0) {
  287.         printf("%d\n", retval);
  288.         return -1;
  289.     }
  290.     printf("OK\n");
  291.    
  292.     printf("%d bytes was read into buffer\n", retval);
  293.     printf("\nContent of the buffer:\n");
  294.     printf(file->share);
  295.     printf("\n\n");
  296.    
  297.     f_err = F_OK;
  298.     return F_OK;
  299. }
  300.  
  301. /**
  302. * Seek to a position within a file
  303. */
  304. int fseek(file_t * file, int offset, int whence) {
  305.     int retval;
  306.     file->params->offset = 0;
  307.     file->params->whence = 0;   /* from beginning of the file */
  308.  
  309.     printf("Request for seeking after %d bytes inside file %s...", file->params->offset, file->params->fname);
  310.     retval = send_request(fs_phone, FS_SEEK, file->params, file->share);
  311.     if (retval < 0) {
  312.         printf("%d\n", retval);
  313.         return -1;
  314.     }
  315.     printf("OK\n");
  316.     printf("New file position is: %d\n", retval);
  317.    
  318.     f_err = F_OK;
  319.     return F_OK;
  320. }
  321.  
  322. /**
  323. * Close a file
  324. */
  325. int fclose(file_t * file) {
  326.     int retval;
  327.    
  328.     printf("Request for closing file %s...", file->params->fname);
  329.     retval = send_request(fs_phone, FS_CLOSE, file->params, file->share);
  330.     if (retval < 0) {
  331.         printf("%d\n", retval);
  332.         return -1;
  333.     }
  334.     printf("OK\n");
  335.    
  336.     if (file != NULL) file_disconnect(file);
  337.    
  338.     f_err = F_OK;
  339.     return F_OK;
  340. }
  341.  
  342. /**
  343. * }
  344. */
  345.