Subversion Repositories HelenOS

Rev

Rev 2433 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2433 jelen 1
/*
2435 jelen 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.
2433 jelen 27
 */
28
 
2435 jelen 29
/** @addtogroup FSDemo
30
 * @{
31
 */
32
 
33
/**
34
 * @file    cat.c
35
 * @brief   A file system demonstration task - raw IPC version
36
 */
37
 
38
 
2433 jelen 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