Subversion Repositories HelenOS

Rev

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

  1. /*
  2.  * Copyright (c) 2007 Michal Konopa
  3.  * Copyright (c) 2007 Martin Jelen
  4.  * Copyright (c) 2007 Peter Majer
  5.  * All rights reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  *
  11.  * - Redistributions of source code must retain the above copyright
  12.  *   notice, this list of conditions and the following disclaimer.
  13.  * - Redistributions in binary form must reproduce the above copyright
  14.  *   notice, this list of conditions and the following disclaimer in the
  15.  *   documentation and/or other materials provided with the distribution.
  16.  * - The name of the author may not be used to endorse or promote products
  17.  *   derived from this software without specific prior written permission.
  18.  *
  19.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  20.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  21.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  22.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  23.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  24.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  25.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  26.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  28.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29.  */
  30.  
  31. /** @addtogroup libc
  32.  * @{
  33.  */
  34.  
  35. /**
  36.  * @file    file.c
  37.  * @brief   The user library for working with the file system
  38.  */
  39.  
  40. #include <stdio.h>
  41. #include <stdlib.h>
  42. #include <string.h>
  43. #include <unistd.h>
  44. #include <async.h>
  45. #include <ipc/services.h>
  46. #include <ipc/ipc.h>
  47. #include <sys/mman.h>
  48. #include <io/file.h>
  49. #include <bool.h>
  50. #include <err.h>
  51. #include <align.h>
  52. #include "../../../fs/dir.h"
  53. #include "../../../share/message.h"
  54. #include "../../../share/shared_proto.h"
  55.  
  56. #define CONNECT_SLEEP_INTERVAL 10000
  57. #define CONNECT_SLEEP_TIMEOUT 100000
  58.  
  59. /**
  60. *
  61. */
  62. static int fs_phone;
  63.  
  64. static file_t *file_connect();
  65. static int file_disconnect(file_t *file);
  66.  
  67. /**
  68.  * Connect to the FS task and share memory with it for further data and
  69.  * extended memory transfers
  70.  */
  71. file_t *file_connect() {
  72.     file_t *result;
  73.    
  74.     size_t size;
  75.     void *share = NULL;
  76.     int retval;
  77.  
  78.     size = ALIGN_UP(BLOCK_SIZE * sizeof(char), PAGE_SIZE);
  79.     share = mmap(share, size, AS_AREA_READ | AS_AREA_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0);
  80.     if ((int) share < 0) {
  81.         f_err = F_MMAP_FAILURE;
  82.         return NULL;
  83.     }
  84.  
  85.     retval = async_req_2(fs_phone, FS_NEW_CONSUMER, task_get_id(), 0, NULL, NULL);
  86.     if (retval < 0) {
  87.         f_err = F_COMM_FAILURE;
  88.         return NULL;
  89.     }
  90.  
  91.     int flags = 0;
  92.     flags = AS_AREA_READ | AS_AREA_WRITE;
  93.     retval = async_req_3(fs_phone, IPC_M_AS_AREA_SEND, (uintptr_t)share, size, flags, NULL, NULL, NULL);
  94.     if (retval < 0) {
  95.         f_err = F_COMM_FAILURE;
  96.         return NULL;
  97.     }
  98.    
  99.     /* Allocating structure for extended message. */
  100.     message_params_t *params = malloc(sizeof(message_params_t));
  101.     memset((void*) params, 0, sizeof(message_params_t));
  102.    
  103.     result = malloc(sizeof(file_t));
  104.     result->share = share;
  105.     result->size = size;
  106.     result->params = params;
  107.    
  108.     f_err = F_OK;
  109.     return result;
  110. }
  111.  
  112. /**
  113.  * Disconnect from the FS task, unsharing memory and freeing the file data structure
  114.  */
  115. int file_disconnect(file_t *file) {
  116.     int retval = send_request(fs_phone, FS_DROP_CONSUMER, file->params, file->share);
  117.     if (retval < 0)
  118.         return -1;
  119.    
  120.     /* Unmapping share area. */
  121.     retval = munmap(file->share, file->size);
  122.     if (retval < 0)
  123.         return -1;
  124.    
  125.     file->size = ALIGN_UP(BLOCK_SIZE * sizeof(char), PAGE_SIZE);
  126.     file->share = mmap(file->share, file->size, AS_AREA_READ | AS_AREA_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0);
  127.     if ((int) (file->share) < 0)
  128.         return -1;
  129.    
  130.     free(file);
  131.     f_err = F_OK;
  132.     return F_OK;
  133. }
  134.  
  135. /**
  136.  * List contents of the current directory
  137.  */
  138. dir_item_t *ls(unsigned int *length) {
  139.     dir_item_t *result;
  140.     unsigned short entries_num;
  141.  
  142.     file_t *shared_file = file_connect();
  143.     if (shared_file == NULL)
  144.         return NULL;
  145.    
  146.     /* We want lookup our work directory. */
  147.     retval = send_request(fs_phone, FS_DSUM, shared_file->params, shared_file->share);
  148.     if (retval < 0) {
  149.         f_err = F_READ_ERROR;
  150.         return NULL;
  151.     }
  152.    
  153.     entries_num = retval;
  154.     *length = entries_num;
  155.    
  156.     result = malloc(entries_num * sizeof (dir_item_t));
  157.    
  158.     int entry;
  159.     for (entry = 0; entry < entries_num; entry++) {
  160.         shared_file->params->entry_number = entry;
  161.         retval = send_request(fs_phone, FS_READENTRY, shared_file->params, shared_file->share);
  162.         if (retval < 0) {
  163.             f_err = F_READ_ERROR;
  164.             return NULL;
  165.         }
  166.        
  167.         memcpy(&(result[entry].inode_num), shared_file->share, sizeof(unsigned short));
  168.         memcpy(result[entry].name, (void *)(shared_file->share+sizeof(unsigned short)), retval-sizeof(unsigned short));
  169.  
  170.         /* Do not show empty entries. */
  171.         if (!result[entry].inode_num)
  172.             continue;
  173.          
  174.     }
  175.     return result;
  176. }
  177.  
  178. /**
  179.  * Change the current working directory for the task
  180.  */
  181. int chdir(char * new_dir)
  182. {
  183.     file_t *shared_file = file_connect();
  184.    
  185.     if (shared_file == NULL) {
  186.         f_err = F_READ_ERROR;
  187.         return F_READ_ERROR;
  188.     }
  189.     memcpy(shared_file->params->fname, new_dir, 30);
  190.    
  191.     int retval = send_request(fs_phone, FS_CHDIR, shared_file->params, shared_file->share);
  192.     if (retval < 0) {
  193.         f_err = F_READ_ERROR;
  194.         return F_READ_ERROR;
  195.     }
  196.  
  197.     retval = file_disconnect(shared_file);
  198.     f_err = F_OK;
  199.     return F_OK;
  200. }
  201.  
  202. /**
  203.  * Open a file for reading and/or writing
  204.  */
  205. file_t *fopen(char *name, int mode)
  206. {
  207.     file_t *file = file_connect();
  208.    
  209.     /* We want to work with the specified file. */ 
  210.     memcpy(file->params->fname, name, 30);
  211.  
  212.     int retval = send_request(fs_phone, FS_OPEN, file->params, file->share);
  213.     if (retval < 0)
  214.         return NULL;
  215.    
  216.     file->handle = retval;
  217.    
  218.     return file;
  219. }
  220.  
  221. /**
  222.  * Read status information about a file
  223.  */
  224. int fstat(file_t *file)
  225. {
  226.     memcpy(file->params->fname, file->base_info.name, 30);
  227.     file->params->fd = file->handle;
  228.  
  229.     int retval = send_request(fs_phone, FS_FSTAT, file->params, file->share);
  230.     if (retval < 0)
  231.         return -1;
  232.    
  233.     memcpy((void *)(&file->stat), file->share, sizeof(stat_t));
  234.    
  235.     f_err = F_OK;
  236.     return F_OK;
  237. }
  238.  
  239. /**
  240.  * Read data from a file
  241.  */
  242. int fread(file_t *file, void* buffer, unsigned int size)
  243. {
  244.     file->params->nbytes = size;
  245.    
  246.     int retval = send_request(fs_phone, FS_READ, file->params, file->share);
  247.     if (retval < 0)
  248.         return -1;
  249.  
  250.     f_err = F_OK;
  251.     return F_OK;
  252. }
  253.  
  254. /**
  255.  * Seek to a position within a file
  256.  */
  257. int fseek(file_t *file, int offset, int whence)
  258. {
  259.     file->params->offset = 0;
  260.     file->params->whence = 0;   /* from beginning of the file */
  261.  
  262.     int retval = send_request(fs_phone, FS_SEEK, file->params, file->share);
  263.     if (retval < 0)
  264.         return -1;
  265.  
  266.     f_err = F_OK;
  267.     return F_OK;
  268. }
  269.  
  270. /**
  271.  * Close a file
  272.  */
  273. int fclose(file_t *file)
  274. {
  275.     int retval = send_request(fs_phone, FS_CLOSE, file->params, file->share);
  276.     if (retval < 0)
  277.         return -1;
  278.  
  279.     if (file != NULL)
  280.         file_disconnect(file);
  281.    
  282.     f_err = F_OK;
  283.     return F_OK;
  284. }
  285.  
  286. /**
  287.  *@}
  288.  */
  289.