Subversion Repositories HelenOS

Rev

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

Rev Author Line No. Line
2433 jelen 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