Subversion Repositories HelenOS

Rev

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

  1. /*
  2.  * Copyright (c) 2007 Konopa-Jelen-Majer
  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 FSDemo
  30.  * @{
  31.  */
  32.  
  33. /**
  34.  * @file    cat.c
  35.  * @brief   A file system demonstration task - raw IPC version
  36.  */
  37.  
  38.  
  39. #include <err.h>
  40. #include <stdio.h>
  41. #include <stdlib.h>
  42. #include <string.h>
  43. #include <unistd.h>
  44. #include <async.h>
  45. #include <align.h>
  46. #include <as.h>
  47. #include <ipc/ipc.h>
  48. #include <ipc/services.h>
  49. #include <sys/mman.h>
  50. #include "../fs/fs.h"
  51. #include "../share/shared_proto.h"
  52. #include "../console/console.h"
  53. #include "../fs/stat.h"
  54.  
  55. #define CON_FS_ATTEMPTS     1000
  56. #define LINE_LENGTH 30
  57. #define EOL 10
  58. #define SPACE_BAR 32
  59. #define CONSOLE_WIDTH 60
  60. #define CONSOLE_HEIGHT 20
  61.  
  62. static int fs_phone;
  63.  
  64.  
  65. /**
  66.  * Reads one line from input (returns after receiving line feed or after reading max_line_length characters)
  67.  * @param max_line_length Maximum line length allowed
  68.  * @return Pointer to read string (null when max_line_length < 0).
  69.  */
  70. static char* input_read(int max_line_length)
  71. {
  72.     if (max_line_length < 0) return NULL;
  73.    
  74.     char * input = malloc(max_line_length+1);
  75.     int c,i;   
  76.    
  77.     char * cpy = input;
  78.     i = 0;
  79.     while ((c = getchar()) != EOL)
  80.     {
  81.         if (++i>max_line_length) break;
  82.         putchar(c);
  83.         memcpy(cpy++,&c,1);
  84.     }
  85.     putchar(EOL);
  86.    
  87.     //adds terminating zero
  88.     memset(cpy,'\0',1);
  89.     return input;
  90. }
  91.  
  92. /**
  93.  * Reads input and returns after receiving continue_string
  94.  * @param continue_sign Returns after receiving this character.
  95.  */
  96. static void wait_for_char(char continue_sign)
  97. {
  98.     printf("- More -\n");
  99.     while (getchar() != continue_sign) {}
  100. }
  101.  
  102.  
  103. /**
  104.  * Writes input string into the console.
  105.  * @param align_size Max width of the output line.
  106.  * @param line_count After printing line_count lines, wait_for_char is called
  107.  * @param reset 1 - resets procedure counters
  108.  */
  109. static void little_more4(char * input, int align_size, int line_count, int reset)
  110. {
  111.     static int lines = 0;
  112.     static int chars = 0;
  113.    
  114.     if (reset)
  115.         lines = chars = 0; 
  116.    
  117.     if ((align_size <= 0) || (line_count <=0)) return;
  118.    
  119.     while(*input != '\0')
  120.     {
  121.         putchar(*input);       
  122.    
  123.         if (*(input++) == EOL)
  124.         {
  125.             chars = 0;
  126.             ++lines;
  127.         }
  128.         else
  129.         {
  130.             ++chars;
  131.             if (chars >= align_size)
  132.             {
  133.                 chars = 0;
  134.                 printf("\n");
  135.                 ++lines;
  136.             }                  
  137.         }      
  138.        
  139.         if (lines >= line_count)
  140.         {
  141.             lines = chars = 0;
  142.             wait_for_char(SPACE_BAR);
  143.         }
  144.     }
  145. }
  146.  
  147. /**
  148.  * Calls little_more(char * input, int align_size, int line_count, int reset) with default values and no reset.
  149.  */
  150. static void little_more(char * input)
  151. {
  152.     little_more4(input, CONSOLE_WIDTH, CONSOLE_HEIGHT, 0);
  153. }
  154.  
  155. /**
  156.  * Calls little_more(char * input, int align_size, int line_count, int reset) with default values.
  157.  */
  158. static void little_more2(char * input, int reset)
  159. {
  160.     little_more4(input, CONSOLE_WIDTH, CONSOLE_HEIGHT, reset);
  161. }
  162.  
  163. static int fopen(char * filename)
  164. {
  165.     return -1;
  166. }
  167.  
  168. static int fclose(int fd)
  169. {
  170.     return -1;
  171. }
  172.  
  173. static int fread(void* ptr, int size, int nbmem, int fd)
  174. {
  175.     return 0;
  176. }
  177.  
  178. /**
  179.  * Simple atoi function (converts the string into an integer)
  180.  * @param str string to convert
  181.  * @return 0 - if error, else converted number
  182.  */
  183. static int my_atoi(char * str)
  184. {
  185.     if (str == NULL) return 0;
  186.     int minus = 0;
  187.     if (str[0] == '-')
  188.     {
  189.         minus = 1;
  190.         ++str;
  191.     };
  192.     int res = 0;
  193.     while (*(str) != '\0')
  194.     {
  195.         res = res*10;
  196.         switch (*(str++))
  197.         {
  198.             case '0':
  199.                 break;
  200.             case '1':
  201.                 ++res;
  202.                 break;
  203.             case '2':
  204.                 res = res + 2;
  205.                 break;
  206.             case '3':
  207.                 res = res + 3;
  208.                 break;             
  209.             case '4':
  210.                 res = res + 4;
  211.                 break;         
  212.             case '5':
  213.                 res = res + 5;
  214.                 break;         
  215.             case '6':
  216.                 res = res + 6;
  217.                 break;         
  218.             case '7':
  219.                 res = res + 7;
  220.                 break;         
  221.             case '8':
  222.                 res = res + 8;
  223.                 break;         
  224.             case '9':
  225.                 res = res + 9;
  226.                 break;
  227.             default: return 0;
  228.         }
  229.     }
  230.     if (minus)
  231.     {
  232.         return -res;
  233.     }
  234.     else
  235.     {
  236.         return res;
  237.     };
  238. }
  239.  
  240.  
  241. /**
  242.  * Simple use of fopen function with some I/O
  243.  */
  244. static void open_file()
  245. {
  246.  
  247.     printf("\n\nEnter the file name:\n? ");
  248.     char * filename = input_read(LINE_LENGTH);
  249.     int fd = fopen(filename);
  250.     if (fd < 0)
  251.     {
  252.         printf("\nfopen failed!\n");
  253.     }
  254.     else
  255.     {
  256.         printf("\nReturned file descriptor: %d\n", fd);
  257.     }
  258. }
  259.  
  260. /**
  261.  * Simple use of fclose function with some I/O
  262.  */
  263. static void close_file()
  264. {
  265.     printf("\n\nEnter the file descriptor:\n? ");
  266.     char * fd_str = input_read(2);
  267.     int fd = my_atoi(fd_str);
  268.     free(fd_str);
  269.    
  270.     if (fclose(fd) < 0)
  271.     {
  272.         printf("\nfclose failed!\n");
  273.     }
  274.     else
  275.     {
  276.         printf("\nFile successfully closed.\n");
  277.     }
  278. }
  279.  
  280. /**
  281.  * Simple use of fread function with some I/O
  282.  */
  283. static void read_file()
  284. {
  285.     printf("\n\nEnter the file descriptor:\n? ");
  286.     char * buf = input_read(2);
  287.     int fd = my_atoi(buf);
  288.     free(buf);
  289.     printf("Enter the no. of elements you want to read:\n? ");
  290.     buf = input_read(5);
  291.     int e_no = my_atoi(buf);
  292.     free(buf);
  293.     printf("Enter the element size (bytes):\n? ");
  294.     buf = input_read(5);
  295.     int e_size = my_atoi(buf);
  296.     free(buf);
  297.     //printf("\nEntered values:\n - fd: %d\n- ec: %d\n- es: %d\n",fd,e_no,e_size);
  298.     void * ptr = malloc(e_no*e_size+1);
  299.     memset(ptr,'\0',e_no*e_size+1);
  300.     int res = fread(ptr, e_no, e_size, fd);
  301.    
  302.     printf ("\nNo. of elements read: %d\n",res);
  303.     printf("Returned data:\n------------\n");
  304.     little_more2(ptr,1);
  305.     printf("\n----EOF-----\n");
  306.     free(ptr);
  307. }
  308.  
  309.  
  310.  
  311.  
  312. int main(int argc, char *argv[])
  313. {
  314.     char fname[30];
  315.     unsigned int file_handle;
  316.     int retval, flags, entry;
  317.     unsigned short entries_num, inode_num;
  318.     size_t size;
  319.     void *share = NULL;
  320.  
  321.        
  322.     little_more2("Cat task\n",1);
  323.  
  324.     little_more("Connecting to the SERVICE_FS...");
  325.     if (!connect_to_fs(&fs_phone, CON_FS_ATTEMPTS)) {
  326.         little_more("Connection to SERVICE_FS was refused\n");
  327.         return -1;
  328.     }
  329.     little_more("OK\n");
  330.    
  331.     little_more("Creating address space area...");
  332.     size = ALIGN_UP(BLOCK_SIZE * sizeof(char), PAGE_SIZE);
  333.     share = mmap(share, size, AS_AREA_READ | AS_AREA_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0);
  334.     if ((int)share < 0){
  335.         little_more("As_area_create error: ");
  336.         printf("%d", (int)share);
  337.         little_more("\n");
  338.         return -1;
  339.     }
  340.     printf("OK\n");
  341.  
  342.     little_more("Connecting the task to FS...");
  343.     retval = async_req_2(fs_phone, FS_NEW_CONSUMER, task_get_id(), 0, NULL, NULL);
  344.     if (retval < 0) {
  345.         printf("%d", retval);
  346.         little_more("\n");
  347.         return -1;
  348.     }
  349.     little_more("OK\n");
  350.  
  351.     little_more("Sending memory to FS_SERVICE...");
  352.     flags = 0;
  353.     flags = AS_AREA_READ | AS_AREA_WRITE;
  354.     retval = async_req_3(fs_phone, IPC_M_AS_AREA_SEND, (uintptr_t)share, size, flags, NULL, NULL, NULL);
  355.     if (retval < 0) {
  356.         printf("%d", retval);
  357.         little_more("\n");
  358.         return -1;
  359.     }
  360.     little_more("OK\n");
  361.    
  362.     /* Allocating structure for extended message. */
  363.     message_params_t *params;
  364.     params = malloc(sizeof(message_params_t));
  365.     memset((void*)params, 0, sizeof(message_params_t));
  366.  
  367.     /* We want lookup our work directory. */
  368.     little_more("Request for get number of entries...");
  369.     retval = send_request(fs_phone, FS_DSUM, params, share);
  370.     if (retval < 0) {
  371.         printf("%d", retval);
  372.         little_more("\n");
  373.         return -1;
  374.     }
  375.     little_more("OK\n");
  376.     little_more("Total number of entries: ");
  377.     printf("%d", retval);
  378.     little_more("\n");
  379.    
  380.    
  381.     entries_num = retval;
  382.    
  383.  
  384.     /* File list in working directory. */
  385.     little_more("File list:\n");
  386.    
  387.     for (entry = 0; entry < entries_num; entry++) {
  388.  
  389.         params->entry_number = entry;
  390.         retval = send_request(fs_phone, FS_READENTRY, params, share);
  391.         if (retval < 0) {
  392.             printf("%d", retval);
  393.             little_more("\n");
  394.             return -1;
  395.         }
  396.         /*
  397.         if (retval < sizeof(unsigned short))
  398.             continue;
  399.         */
  400.         memcpy(&inode_num, share, sizeof(unsigned short));
  401.         memcpy(fname, (void *)(share+sizeof(unsigned short)), retval-sizeof(unsigned short));
  402.  
  403.         /* Do not show empty entries. */
  404.         if (!inode_num)
  405.             continue;
  406.          
  407.         little_more("Inode number: ");
  408.         printf("%u", inode_num);
  409.         little_more("\t\t");
  410.         little_more("File name: ");
  411.         little_more(fname);
  412.         little_more("\n");
  413.        
  414.     }
  415.     little_more("OK\n");
  416.    
  417.     /* We want to change working directory */
  418.     memcpy(fname, "uspace/fs", 10);
  419.     memcpy(params->fname, fname, 10);
  420.    
  421.     little_more("Request for changing actual directory to ");
  422.     little_more(fname);
  423.     little_more("...");
  424.     retval = send_request(fs_phone, FS_CHDIR, params, share);
  425.     if (retval < 0) {
  426.         printf("%d", retval);
  427.         little_more("\n");
  428.         return -1;
  429.     }
  430.     little_more("OK\n");
  431.  
  432.     /* We want to work with specified file. */
  433.     memcpy(fname, "fs.c", 10);
  434.     memcpy(params->fname, fname, 10);
  435.  
  436.     little_more("Request for opening file ");
  437.     little_more(fname);
  438.     little_more("...");
  439.     retval = send_request(fs_phone, FS_OPEN, params, share);
  440.     if (retval < 0) {
  441.         printf("%d", retval);
  442.         little_more("\n");     
  443.         return -1;
  444.     }
  445.     little_more("OK\n");
  446.  
  447.     file_handle = retval;
  448.     little_more("Returned file handle...");
  449.     printf("%d", file_handle);
  450.     little_more("\n");
  451.    
  452.     memcpy(params->fname, fname, 10);
  453.     params->fd = file_handle;
  454.  
  455.     little_more("Request for getting info about file ");
  456.     little_more(fname);
  457.     little_more("[FSTAT called]...");
  458.     retval = send_request(fs_phone, FS_FSTAT, params, share);
  459.     if (retval < 0) {
  460.         printf("%d", retval);
  461.         little_more("\n"); 
  462.         return -1;
  463.     }
  464.     little_more("OK\n");
  465.    
  466.     params->fd = file_handle;
  467.     params->offset = 100;
  468.     params->whence = 1; /* from actual position in the file */
  469.  
  470.     little_more("Request for seeking after ");
  471.     printf("%d", params->offset);
  472.     little_more(" bytes inside file ");
  473.     little_more(fname);
  474.     little_more("...");
  475.     retval = send_request(fs_phone, FS_SEEK, params, share);
  476.     if (retval < 0) {
  477.         printf("%d", retval);
  478.         little_more("\n");         
  479.         return -1;
  480.     }
  481.     little_more("OK\n");
  482.  
  483.     little_more("New file position is: ");
  484.     printf("%d", retval);
  485.     little_more("\n");
  486.    
  487.     params->nbytes = 100;
  488.    
  489.     little_more("Request for reading ");
  490.     printf("%d", params->nbytes);
  491.     little_more(" bytes from file ");
  492.     little_more(fname);
  493.     little_more("...");
  494.    
  495.     retval = send_request(fs_phone, FS_READ, params, share);
  496.     if (retval < 0) {
  497.         printf("%d", retval);
  498.         little_more("\n"); 
  499.         return -1;
  500.     }
  501.     little_more("OK\n");
  502.    
  503.     printf("%d", retval);
  504.     little_more(" bytes was read into buffer\n");
  505.     little_more("\nContent of the buffer:\n");
  506.     little_more(share);
  507.     little_more("\n\n");   
  508.    
  509.    
  510.     params->offset = 0;
  511.     params->whence = 0; /* from beginning of the file */
  512.  
  513.     little_more("Request for seeking after ");
  514.     printf("%d", params->offset);
  515.     little_more(" bytes inside file ");
  516.     little_more(fname);
  517.     little_more("...");
  518.     retval = send_request(fs_phone, FS_SEEK, params, share);
  519.     if (retval < 0) {
  520.         printf("%d", retval);
  521.         little_more("\n"); 
  522.         return -1;
  523.     }
  524.     little_more("OK\n");
  525.    
  526.     little_more("New file position is: ");
  527.     printf("%d", retval);
  528.     little_more("\n");
  529.     params->fd = file_handle;
  530.    
  531.     params->nbytes = 50;
  532.  
  533.     little_more("Another request for reading ");
  534.     printf("%d", params->nbytes);
  535.     little_more(" bytes from file ");
  536.     little_more(fname);
  537.     little_more("...");
  538.     retval = send_request(fs_phone, FS_READ, params, share);
  539.     if (retval < 0) {
  540.         printf("%d", retval);
  541.         little_more("\n");         
  542.         return -1;
  543.     }
  544.     little_more("OK\n");
  545.  
  546.     printf("%d", retval);
  547.     little_more(" bytes was read into buffer\n");
  548.     little_more("\nContent of the buffer:\n");
  549.     little_more(share);
  550.     little_more("\n\n");
  551.  
  552.     little_more("Request for closing file ");
  553.     little_more(fname);
  554.     little_more("...");
  555.     retval = send_request(fs_phone, FS_CLOSE, params, share);
  556.     if (retval < 0) {
  557.         printf("%d", retval);
  558.         little_more("\n");         
  559.         return -1;
  560.     }
  561.     little_more("OK\n");
  562.  
  563.    
  564.     /*
  565.     printf("Request for closing file %s once more...", fname);
  566.     retval = send_request(fs_phone, FS_CLOSE, params, share);
  567.     if (retval < 0) {
  568.         printf("%d\n", retval);
  569.         return -1;
  570.     }
  571.     printf("OK\n");
  572.     */
  573.  
  574.     little_more("Request for dropping the connection to the FS...");
  575.     retval = send_request(fs_phone, FS_DROP_CONSUMER, params, share);
  576.     if (retval < 0) {
  577.         printf("%d", retval);
  578.         little_more("\n");         
  579.         return -1;
  580.     }
  581.     little_more("OK\n");
  582.  
  583.    
  584.    
  585.     /* Unmapping share area. */
  586.     little_more("Unmapping share area...");
  587.     retval = munmap(share, size);
  588.     if (retval < 0) {
  589.         printf("%d", retval);
  590.         little_more("\n");         
  591.         return -1;
  592.     }
  593.     little_more("OK\n");
  594.    
  595.     little_more("Creating address space area...");
  596.     size = ALIGN_UP(BLOCK_SIZE * sizeof(char), PAGE_SIZE);
  597.     share = mmap(share, size, AS_AREA_READ | AS_AREA_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0);
  598.     if ((int)share < 0){
  599.         little_more("As_area_create error: ");
  600.         printf("%d");
  601.         little_more("\n");
  602.         return -1;
  603.     }
  604.     little_more("OK\n");
  605.  
  606.     /* Next connection to the FS. */
  607.     little_more("Connecting the task to FS...");
  608.     retval = async_req_2(fs_phone, FS_NEW_CONSUMER, task_get_id(), 0, NULL, NULL);
  609.     if (retval < 0) {
  610.         little_more("FS_NEW_CONSUMER error: ");
  611.         printf("%d", retval);
  612.         little_more("\n");
  613.         return -1;
  614.     }
  615.     little_more("OK\n");
  616.    
  617.     little_more("Sending memory to FS_SERVICE...");
  618.     flags = 0;
  619.     flags = AS_AREA_READ | AS_AREA_WRITE;
  620.     retval = async_req_3(fs_phone, IPC_M_AS_AREA_SEND, (uintptr_t)share, size, flags, NULL, NULL, NULL);
  621.     if (retval < 0) {
  622.         printf("%d", retval);
  623.         little_more("\n");         
  624.         return -1;
  625.     }
  626.     little_more("OK\n");
  627.  
  628.     /* We want to work with specified file. */
  629.     memcpy(fname, "/kernel/arch", 20);
  630.     memcpy(params->fname, fname, 20);
  631.  
  632.     little_more("Request for getting info about file ");   
  633.     little_more(fname);
  634.     little_more("[STAT called]...");   
  635.     retval = send_request(fs_phone, FS_STAT, params, share);
  636.     if (retval < 0) {
  637.         printf("%d", retval);
  638.         little_more("\n");         
  639.         return -1;
  640.     }
  641.     little_more("OK\n");
  642.    
  643.     stat_t file_info;
  644.     memcpy((void *)(&file_info), share, sizeof(stat_t));
  645.  
  646.     little_more("Info about file: ");
  647.     little_more(fname);
  648.     little_more("\nInode number: ");
  649.     printf("%d", file_info.st_ino);
  650.     little_more("\nMode: ");
  651.     printf("%d", file_info.st_mode);
  652.     little_more("\nLinks: ");
  653.     printf("%d", file_info.st_nlink);
  654.     little_more("\nSize: ");
  655.     printf("%d", file_info.st_size);
  656.     little_more("\n");
  657.    
  658.    
  659.     //==================================================================================
  660.     while(1)
  661.     {
  662.         printf("\n\n\n- <stdio.h> calls -\n\n");
  663.         printf("What do you want to do?\n");
  664.         printf("o - open some file\n");
  665.         printf("c - close some file\n");
  666.         printf("r - read some file\n");
  667.         printf("? ");
  668.         char * choice = input_read(1);
  669.        
  670.         switch (choice[0])
  671.         {
  672.             case 'o':
  673.                 open_file();
  674.                 break;
  675.             case 'c':
  676.                 close_file();
  677.                 break;
  678.             case 'r':
  679.                 read_file();
  680.                 break;
  681.         }
  682.         free(choice);
  683.         wait_for_char(SPACE_BAR);
  684.         printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
  685.     }
  686.     return 0;
  687. }
  688.  
  689.  
  690.