Subversion Repositories HelenOS

Rev

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

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