Subversion Repositories HelenOS

Rev

Rev 2699 | Rev 2707 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (c) 2008 Jakub Jermar
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  *
  9.  * - Redistributions of source code must retain the above copyright
  10.  *   notice, this list of conditions and the following disclaimer.
  11.  * - Redistributions in binary form must reproduce the above copyright
  12.  *   notice, this list of conditions and the following disclaimer in the
  13.  *   documentation and/or other materials provided with the distribution.
  14.  * - The name of the author may not be used to endorse or promote products
  15.  *   derived from this software without specific prior written permission.
  16.  *
  17.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27.  */
  28.  
  29. /** @addtogroup libc
  30.  * @{
  31.  */
  32. /** @file
  33.  */
  34.  
  35. #include <vfs.h>
  36. #include <stdlib.h>
  37. #include <unistd.h>
  38. #include <dirent.h>
  39. #include <fcntl.h>
  40. #include <ipc/ipc.h>
  41. #include <ipc/services.h>
  42. #include <async.h>
  43. #include <atomic.h>
  44. #include <futex.h>
  45. #include <errno.h>
  46. #include <string.h>
  47. #include "../../srv/vfs/vfs.h"
  48.  
  49. int vfs_phone = -1;
  50. atomic_t vfs_phone_futex = FUTEX_INITIALIZER;
  51.  
  52. static int vfs_connect(void)
  53. {
  54.     if (vfs_phone < 0)
  55.         vfs_phone = ipc_connect_me_to(PHONE_NS, SERVICE_VFS, 0, 0);
  56.     return vfs_phone;
  57. }
  58.  
  59. int mount(const char *fs_name, const char *mp, const char *dev)
  60. {
  61.     int res;
  62.     ipcarg_t rc;
  63.     aid_t req;
  64.  
  65.     int dev_handle = 0; /* TODO */
  66.  
  67.     futex_down(&vfs_phone_futex);
  68.     async_serialize_start();
  69.     if (vfs_phone < 0) {
  70.         res = vfs_connect();
  71.         if (res < 0) {
  72.             async_serialize_end();
  73.             futex_up(&vfs_phone_futex);
  74.             return res;
  75.         }
  76.     }
  77.     req = async_send_1(vfs_phone, VFS_MOUNT, dev_handle, NULL);
  78.     rc = ipc_data_write_start(vfs_phone, (void *)fs_name, strlen(fs_name));
  79.     if (rc != EOK) {
  80.         async_wait_for(req, NULL);
  81.         async_serialize_end();
  82.         futex_up(&vfs_phone_futex);
  83.         return (int) rc;
  84.     }
  85.     rc = ipc_data_write_start(vfs_phone, (void *)mp, strlen(mp));
  86.     if (rc != EOK) {
  87.         async_wait_for(req, NULL);
  88.         async_serialize_end();
  89.         futex_up(&vfs_phone_futex);
  90.         return (int) rc;
  91.     }
  92.     async_wait_for(req, &rc);
  93.     async_serialize_end();
  94.     futex_up(&vfs_phone_futex);
  95.     return (int) rc;
  96. }
  97.  
  98. static int _open(const char *path, int lflag, int oflag, ...)
  99. {
  100.     int res;
  101.     ipcarg_t rc;
  102.     ipc_call_t answer;
  103.     aid_t req;
  104.    
  105.     futex_down(&vfs_phone_futex);
  106.     async_serialize_start();
  107.     if (vfs_phone < 0) {
  108.         res = vfs_connect();
  109.         if (res < 0) {
  110.             async_serialize_end();
  111.             futex_up(&vfs_phone_futex);
  112.             return res;
  113.         }
  114.     }
  115.     req = async_send_3(vfs_phone, VFS_OPEN, lflag, oflag, 0, &answer);
  116.     rc = ipc_data_write_start(vfs_phone, path, strlen(path));
  117.     if (rc != EOK) {
  118.         async_wait_for(req, NULL);
  119.         async_serialize_end();
  120.         futex_up(&vfs_phone_futex);
  121.         return (int) rc;
  122.     }
  123.     async_wait_for(req, &rc);
  124.     async_serialize_end();
  125.     futex_up(&vfs_phone_futex);
  126.     return (int) IPC_GET_ARG1(answer);
  127. }
  128.  
  129. int open(const char *path, int oflag, ...)
  130. {
  131.     return _open(path, L_FILE, oflag);
  132. }
  133.  
  134. ssize_t read(int fildes, void *buf, size_t nbyte)
  135. {
  136.     int res;
  137.     ipcarg_t rc;
  138.     ipc_call_t answer;
  139.     aid_t req;
  140.  
  141.     futex_down(&vfs_phone_futex);
  142.     async_serialize_start();
  143.     if (vfs_phone < 0) {
  144.         res = vfs_connect();
  145.         if (res < 0) {
  146.             async_serialize_end();
  147.             futex_up(&vfs_phone_futex);
  148.             return res;
  149.         }
  150.     }
  151.     req = async_send_1(vfs_phone, VFS_READ, fildes, &answer);
  152.     if (ipc_data_read_start(vfs_phone, (void *)buf, nbyte) != EOK) {
  153.         async_wait_for(req, NULL);
  154.         async_serialize_end();
  155.         futex_up(&vfs_phone_futex);
  156.         return (ssize_t) rc;
  157.     }
  158.     async_wait_for(req, &rc);
  159.     async_serialize_end();
  160.     futex_up(&vfs_phone_futex);
  161.     return (ssize_t) IPC_GET_ARG1(answer);
  162. }
  163.  
  164. ssize_t write(int fildes, const void *buf, size_t nbyte)
  165. {
  166.     int res;
  167.     ipcarg_t rc;
  168.     ipc_call_t answer;
  169.     aid_t req;
  170.  
  171.     futex_down(&vfs_phone_futex);
  172.     async_serialize_start();
  173.     if (vfs_phone < 0) {
  174.         res = vfs_connect();
  175.         if (res < 0) {
  176.             async_serialize_end();
  177.             futex_up(&vfs_phone_futex);
  178.             return res;
  179.         }
  180.     }
  181.     req = async_send_1(vfs_phone, VFS_WRITE, fildes, &answer);
  182.     if (ipc_data_write_start(vfs_phone, (void *)buf, nbyte) != EOK) {
  183.         async_wait_for(req, NULL);
  184.         async_serialize_end();
  185.         futex_up(&vfs_phone_futex);
  186.         return (ssize_t) rc;
  187.     }
  188.     async_wait_for(req, &rc);
  189.     async_serialize_end();
  190.     futex_up(&vfs_phone_futex);
  191.     return (ssize_t) IPC_GET_ARG1(answer);
  192. }
  193.  
  194. off_t lseek(int fildes, off_t offset, int whence)
  195. {
  196.     int res;
  197.     ipcarg_t rc;
  198.  
  199.     futex_down(&vfs_phone_futex);
  200.     async_serialize_start();
  201.     if (vfs_phone < 0) {
  202.         res = vfs_connect();
  203.         if (res < 0) {
  204.             async_serialize_end();
  205.             futex_up(&vfs_phone_futex);
  206.             return res;
  207.         }
  208.     }
  209.        
  210.     off_t newoffs;
  211.     rc = async_req_3_1(vfs_phone, VFS_SEEK, fildes, offset, whence,
  212.         &newoffs);
  213.  
  214.     async_serialize_end();
  215.     futex_up(&vfs_phone_futex);
  216.  
  217.     if (rc != EOK)
  218.         return (off_t) -1;
  219.    
  220.     return newoffs;
  221. }
  222.  
  223. int ftruncate(int fildes, off_t length)
  224. {
  225.     int res;
  226.     ipcarg_t rc;
  227.    
  228.     futex_down(&vfs_phone_futex);
  229.     async_serialize_start();
  230.     if (vfs_phone < 0) {
  231.         res = vfs_connect();
  232.         if (res < 0) {
  233.             async_serialize_end();
  234.             futex_up(&vfs_phone_futex);
  235.             return res;
  236.         }
  237.     }
  238.     rc = async_req_2_0(vfs_phone, VFS_TRUNCATE, fildes, length);
  239.     async_serialize_end();
  240.     futex_up(&vfs_phone_futex);
  241.     return (int) rc;
  242. }
  243.  
  244. DIR *opendir(const char *dirname)
  245. {
  246.     DIR *dirp = malloc(sizeof(DIR));
  247.     if (!dirp)
  248.         return NULL;
  249.     dirp->fd = _open(dirname, L_DIRECTORY, 0);
  250.     if (dirp->fd < 0) {
  251.         free(dirp);
  252.         return NULL;
  253.     }
  254.     return dirp;
  255. }
  256.  
  257. struct dirent *readdir(DIR *dirp)
  258. {
  259.     ssize_t len = read(dirp->fd, &dirp->res.d_name[0], NAME_MAX + 1);
  260.     if (len <= 0)
  261.         return NULL;
  262.     return &dirp->res;
  263. }
  264.  
  265. void rewinddir(DIR *dirp)
  266. {
  267.     (void) lseek(dirp->fd, 0, SEEK_SET);
  268. }
  269.  
  270. int closedir(DIR *dirp)
  271. {
  272.     (void) close(dirp->fd);
  273.     free(dirp);
  274.     return 0;
  275. }
  276.  
  277. int close(int fildes)
  278. {
  279.     return 0;   /* TODO */
  280. }
  281.  
  282. /** @}
  283.  */
  284.