Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2432 → Rev 2433

/branches/fs/uspace/cat/cat.c
1,303 → 1,655
/*
* Cat
*/
 
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <async.h>
#include <align.h>
#include <as.h>
#include <ipc/ipc.h>
#include <ipc/services.h>
#include <sys/mman.h>
#include "../fs/fs.h"
#include "../share/shared_proto.h"
#include "../console/console.h"
#include "../fs/stat.h"
 
#define CON_FS_ATTEMPTS 1000
 
static int fs_phone;
 
int main(int argc, char *argv[])
{
char fname[30];
unsigned int file_handle;
int retval, flags, entry;
unsigned short entries_num, inode_num;
size_t size;
void *share = NULL;
 
printf("Cat task\n");
 
printf("Connecting to the SERVICE_FS...");
if (!connect_to_fs(&fs_phone, CON_FS_ATTEMPTS)) {
printf("Connection to SERVICE_FS was refused\n");
return -1;
}
printf("OK\n");
printf("Creating address space area...");
size = ALIGN_UP(BLOCK_SIZE * sizeof(char), PAGE_SIZE);
share = mmap(share, size, AS_AREA_READ | AS_AREA_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0);
if ((int)share < 0){
printf("As_area_create error: %d\n", (int)share);
return -1;
}
printf("OK\n");
 
printf("Connecting the task to FS...");
retval = async_req_2(fs_phone, FS_NEW_CONSUMER, task_get_id(), 0, NULL, NULL);
if (retval < 0) {
printf("%d\n", retval);
return -1;
}
printf("OK\n");
 
printf("Sending memory to FS_SERVICE...");
flags = 0;
flags = AS_AREA_READ | AS_AREA_WRITE;
retval = async_req_3(fs_phone, IPC_M_AS_AREA_SEND, (uintptr_t)share, size, flags, NULL, NULL, NULL);
if (retval < 0) {
printf("%d\n", retval);
return -1;
}
printf("OK\n");
/* Allocating structure for extended message. */
message_params_t *params;
params = malloc(sizeof(message_params_t));
memset((void*)params, 0, sizeof(message_params_t));
 
/* We want lookup our work directory. */
printf("Request for get number of entries...");
retval = send_request(fs_phone, FS_DSUM, params, share);
if (retval < 0) {
printf("%d\n", retval);
return -1;
}
printf("OK\n");
printf("Total number of entries: %d\n", retval);
entries_num = retval;
 
/* File list in working directory. */
printf("File list:\n");
for (entry = 0; entry < entries_num; entry++) {
 
params->entry_number = entry;
retval = send_request(fs_phone, FS_READENTRY, params, share);
if (retval < 0) {
printf("%d\n", retval);
return -1;
}
/*
if (retval < sizeof(unsigned short))
continue;
*/
memcpy(&inode_num, share, sizeof(unsigned short));
memcpy(fname, (void *)(share+sizeof(unsigned short)), retval-sizeof(unsigned short));
 
/* Do not show empty entries. */
if (!inode_num)
continue;
printf("Inode number: %u\t\t", inode_num);
printf("File name: %s\n", fname);
}
printf("OK\n");
/* We want to change working directory */
memcpy(fname, "uspace/fs", 10);
memcpy(params->fname, fname, 10);
 
printf("Request for changing actual directory to %s...", fname);
retval = send_request(fs_phone, FS_CHDIR, params, share);
if (retval < 0) {
printf("%d\n", retval);
return -1;
}
printf("OK\n");
 
/* We want to work with specified file. */
memcpy(fname, "fs.c", 10);
memcpy(params->fname, fname, 10);
 
printf("Request for opening file %s...", fname);
retval = send_request(fs_phone, FS_OPEN, params, share);
if (retval < 0) {
printf("%d\n", retval);
return -1;
}
printf("OK\n");
 
file_handle = retval;
printf("Returned file handle...%d\n", file_handle);
memcpy(params->fname, fname, 10);
params->fd = file_handle;
 
printf("Request for getting info about file %s[FSTAT called]...", fname);
retval = send_request(fs_phone, FS_FSTAT, params, share);
if (retval < 0) {
printf("%d\n", retval);
return -1;
}
printf("OK\n");
params->fd = file_handle;
params->offset = 100;
params->whence = 1; /* from actual position in the file */
 
printf("Request for seeking after %d bytes inside file %s...", params->offset, fname);
retval = send_request(fs_phone, FS_SEEK, params, share);
if (retval < 0) {
printf("%d\n", retval);
return -1;
}
printf("OK\n");
 
printf("New file position is: %d\n", retval);
params->nbytes = 100;
printf("Request for reading %d bytes from file %s...", params->nbytes, fname);
retval = send_request(fs_phone, FS_READ, params, share);
if (retval < 0) {
printf("%d\n", retval);
return -1;
}
printf("OK\n");
printf("%d bytes was read into buffer\n", retval);
printf("\nContent of the buffer:\n");
printf(share);
printf("\n\n");
params->offset = 0;
params->whence = 0; /* from beginning of the file */
 
printf("Request for seeking after %d bytes inside file %s...", params->offset, fname);
retval = send_request(fs_phone, FS_SEEK, params, share);
if (retval < 0) {
printf("%d\n", retval);
return -1;
}
printf("OK\n");
 
printf("New file position is: %d\n", retval);
params->fd = file_handle;
params->nbytes = 50;
 
printf("Another request for reading %d bytes from file %s...", params->nbytes, fname);
retval = send_request(fs_phone, FS_READ, params, share);
if (retval < 0) {
printf("%d\n", retval);
return -1;
}
printf("OK\n");
 
printf("%d bytes was read into buffer\n", retval);
printf("\nContent of the buffer:\n");
printf(share);
printf("\n\n");
 
 
printf("Request for closing file %s...", fname);
retval = send_request(fs_phone, FS_CLOSE, params, share);
if (retval < 0) {
printf("%d\n", retval);
return -1;
}
printf("OK\n");
/*
printf("Request for closing file %s once more...", fname);
retval = send_request(fs_phone, FS_CLOSE, params, share);
if (retval < 0) {
printf("%d\n", retval);
return -1;
}
printf("OK\n");
*/
 
printf("Request for dropping the connection to the FS...");
retval = send_request(fs_phone, FS_DROP_CONSUMER, params, share);
if (retval < 0) {
printf("%d\n", retval);
return -1;
}
printf("OK\n");
/* Unmapping share area. */
printf("Unmapping share area...");
retval = munmap(share, size);
if (retval < 0) {
printf("%d\n", retval);
return -1;
}
printf("OK\n");
printf("Creating address space area...");
size = ALIGN_UP(BLOCK_SIZE * sizeof(char), PAGE_SIZE);
share = mmap(share, size, AS_AREA_READ | AS_AREA_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0);
if ((int)share < 0){
printf("As_area_create error: %d\n", (int)share);
return -1;
}
printf("OK\n");
 
/* Next connection to the FS. */
printf("Connecting the task to FS...");
retval = async_req_2(fs_phone, FS_NEW_CONSUMER, task_get_id(), 0, NULL, NULL);
if (retval < 0) {
printf("FS_NEW_CONSUMER error: %d\n", retval);
return -1;
}
printf("OK\n");
printf("Sending memory to FS_SERVICE...");
flags = 0;
flags = AS_AREA_READ | AS_AREA_WRITE;
retval = async_req_3(fs_phone, IPC_M_AS_AREA_SEND, (uintptr_t)share, size, flags, NULL, NULL, NULL);
if (retval < 0) {
printf("%d\n", retval);
return -1;
}
printf("OK\n");
 
/* We want to work with specified file. */
memcpy(fname, "/kernel/arch", 20);
memcpy(params->fname, fname, 20);
 
printf("Request for getting info about file %s[STAT called]...", fname);
retval = send_request(fs_phone, FS_STAT, params, share);
if (retval < 0) {
printf("%d\n", retval);
return -1;
}
printf("OK\n");
stat_t file_info;
memcpy((void *)(&file_info), share, sizeof(stat_t));
 
printf("Info about file: %s\n", fname);
printf("Inode number: %d\n", file_info.st_ino);
printf("Mode: %d\n", file_info.st_mode);
printf("Links: %d\n", file_info.st_nlink);
printf("Size: %d\n", file_info.st_size);
return 0;
}
 
/*
* Cat
*/
 
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <async.h>
#include <align.h>
#include <as.h>
#include <ipc/ipc.h>
#include <ipc/services.h>
#include <sys/mman.h>
#include "../fs/fs.h"
#include "../share/shared_proto.h"
#include "../console/console.h"
#include "../fs/stat.h"
 
#define CON_FS_ATTEMPTS 1000
#define LINE_LENGTH 30
#define EOL 10
#define SPACE_BAR 32
#define CONSOLE_WIDTH 60
#define CONSOLE_HEIGHT 20
 
static int fs_phone;
 
 
/**
* Reads one line from input (returns after receiving line feed or after reading max_line_length characters)
* @param max_line_length Maximum line length allowed
* @return Pointer to read string (null when max_line_length < 0).
*/
static char* input_read(int max_line_length)
{
if (max_line_length < 0) return NULL;
char * input = malloc(max_line_length+1);
int c,i;
char * cpy = input;
i = 0;
while ((c = getchar()) != EOL)
{
if (++i>max_line_length) break;
putchar(c);
memcpy(cpy++,&c,1);
}
putchar(EOL);
//adds terminating zero
memset(cpy,'\0',1);
return input;
}
 
/**
* Reads input and returns after receiving continue_string
* @param continue_sign Returns after receiving this character.
*/
static void wait_for_char(char continue_sign)
{
printf("- More -\n");
while (getchar() != continue_sign) {}
}
 
 
/**
* Writes input string into the console.
* @param align_size Max width of the output line.
* @param line_count After printing line_count lines, wait_for_char is called
* @param reset 1 - resets procedure counters
*/
static void little_more4(char * input, int align_size, int line_count, int reset)
{
static int lines = 0;
static int chars = 0;
if (reset)
lines = chars = 0;
if ((align_size <= 0) || (line_count <=0)) return;
while(*input != '\0')
{
putchar(*input);
if (*(input++) == EOL)
{
chars = 0;
++lines;
}
else
{
++chars;
if (chars >= align_size)
{
chars = 0;
printf("\n");
++lines;
}
}
if (lines >= line_count)
{
lines = chars = 0;
wait_for_char(SPACE_BAR);
}
}
}
 
/**
* Calls little_more(char * input, int align_size, int line_count, int reset) with default values and no reset.
*/
static void little_more(char * input)
{
little_more4(input, CONSOLE_WIDTH, CONSOLE_HEIGHT, 0);
}
 
/**
* Calls little_more(char * input, int align_size, int line_count, int reset) with default values.
*/
static void little_more2(char * input, int reset)
{
little_more4(input, CONSOLE_WIDTH, CONSOLE_HEIGHT, reset);
}
 
static int fopen(char * filename)
{
return -1;
}
 
static int fclose(int fd)
{
return -1;
}
 
static int fread(void* ptr, int size, int nbmem, int fd)
{
return 0;
}
 
/**
* Simple atoi function (converts the string into an integer)
* @param str string to convert
* @return 0 - if error, else converted number
*/
static int my_atoi(char * str)
{
if (str == NULL) return 0;
int minus = 0;
if (str[0] == '-')
{
minus = 1;
++str;
};
int res = 0;
while (*(str) != '\0')
{
res = res*10;
switch (*(str++))
{
case '0':
break;
case '1':
++res;
break;
case '2':
res = res + 2;
break;
case '3':
res = res + 3;
break;
case '4':
res = res + 4;
break;
case '5':
res = res + 5;
break;
case '6':
res = res + 6;
break;
case '7':
res = res + 7;
break;
case '8':
res = res + 8;
break;
case '9':
res = res + 9;
break;
default: return 0;
}
}
if (minus)
{
return -res;
}
else
{
return res;
};
}
 
 
/**
* Simple use of fopen function with some I/O
*/
static void open_file()
{
 
printf("\n\nEnter the file name:\n? ");
char * filename = input_read(LINE_LENGTH);
int fd = fopen(filename);
if (fd < 0)
{
printf("\nfopen failed!\n");
}
else
{
printf("\nReturned file descriptor: %d\n", fd);
}
}
 
/**
* Simple use of fclose function with some I/O
*/
static void close_file()
{
printf("\n\nEnter the file descriptor:\n? ");
char * fd_str = input_read(2);
int fd = my_atoi(fd_str);
free(fd_str);
if (fclose(fd) < 0)
{
printf("\nfclose failed!\n");
}
else
{
printf("\nFile successfully closed.\n");
}
}
 
/**
* Simple use of fread function with some I/O
*/
static void read_file()
{
printf("\n\nEnter the file descriptor:\n? ");
char * buf = input_read(2);
int fd = my_atoi(buf);
free(buf);
printf("Enter the no. of elements you want to read:\n? ");
buf = input_read(5);
int e_no = my_atoi(buf);
free(buf);
printf("Enter the element size (bytes):\n? ");
buf = input_read(5);
int e_size = my_atoi(buf);
free(buf);
//printf("\nEntered values:\n - fd: %d\n- ec: %d\n- es: %d\n",fd,e_no,e_size);
void * ptr = malloc(e_no*e_size+1);
memset(ptr,'\0',e_no*e_size+1);
int res = fread(ptr, e_no, e_size, fd);
printf ("\nNo. of elements read: %d\n",res);
printf("Returned data:\n------------\n");
little_more2(ptr,1);
printf("\n----EOF-----\n");
free(ptr);
}
 
 
 
 
int main(int argc, char *argv[])
{
char fname[30];
unsigned int file_handle;
int retval, flags, entry;
unsigned short entries_num, inode_num;
size_t size;
void *share = NULL;
 
little_more2("Cat task\n",1);
 
little_more("Connecting to the SERVICE_FS...");
if (!connect_to_fs(&fs_phone, CON_FS_ATTEMPTS)) {
little_more("Connection to SERVICE_FS was refused\n");
return -1;
}
little_more("OK\n");
little_more("Creating address space area...");
size = ALIGN_UP(BLOCK_SIZE * sizeof(char), PAGE_SIZE);
share = mmap(share, size, AS_AREA_READ | AS_AREA_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0);
if ((int)share < 0){
little_more("As_area_create error: ");
printf("%d", (int)share);
little_more("\n");
return -1;
}
printf("OK\n");
 
little_more("Connecting the task to FS...");
retval = async_req_2(fs_phone, FS_NEW_CONSUMER, task_get_id(), 0, NULL, NULL);
if (retval < 0) {
printf("%d", retval);
little_more("\n");
return -1;
}
little_more("OK\n");
 
little_more("Sending memory to FS_SERVICE...");
flags = 0;
flags = AS_AREA_READ | AS_AREA_WRITE;
retval = async_req_3(fs_phone, IPC_M_AS_AREA_SEND, (uintptr_t)share, size, flags, NULL, NULL, NULL);
if (retval < 0) {
printf("%d", retval);
little_more("\n");
return -1;
}
little_more("OK\n");
/* Allocating structure for extended message. */
message_params_t *params;
params = malloc(sizeof(message_params_t));
memset((void*)params, 0, sizeof(message_params_t));
 
/* We want lookup our work directory. */
little_more("Request for get number of entries...");
retval = send_request(fs_phone, FS_DSUM, params, share);
if (retval < 0) {
printf("%d", retval);
little_more("\n");
return -1;
}
little_more("OK\n");
little_more("Total number of entries: ");
printf("%d", retval);
little_more("\n");
entries_num = retval;
 
/* File list in working directory. */
little_more("File list:\n");
for (entry = 0; entry < entries_num; entry++) {
 
params->entry_number = entry;
retval = send_request(fs_phone, FS_READENTRY, params, share);
if (retval < 0) {
printf("%d", retval);
little_more("\n");
return -1;
}
/*
if (retval < sizeof(unsigned short))
continue;
*/
memcpy(&inode_num, share, sizeof(unsigned short));
memcpy(fname, (void *)(share+sizeof(unsigned short)), retval-sizeof(unsigned short));
 
/* Do not show empty entries. */
if (!inode_num)
continue;
little_more("Inode number: ");
printf("%u", inode_num);
little_more("\t\t");
little_more("File name: ");
little_more(fname);
little_more("\n");
}
little_more("OK\n");
/* We want to change working directory */
memcpy(fname, "uspace/fs", 10);
memcpy(params->fname, fname, 10);
little_more("Request for changing actual directory to ");
little_more(fname);
little_more("...");
retval = send_request(fs_phone, FS_CHDIR, params, share);
if (retval < 0) {
printf("%d", retval);
little_more("\n");
return -1;
}
little_more("OK\n");
 
/* We want to work with specified file. */
memcpy(fname, "fs.c", 10);
memcpy(params->fname, fname, 10);
 
little_more("Request for opening file ");
little_more(fname);
little_more("...");
retval = send_request(fs_phone, FS_OPEN, params, share);
if (retval < 0) {
printf("%d", retval);
little_more("\n");
return -1;
}
little_more("OK\n");
 
file_handle = retval;
little_more("Returned file handle...");
printf("%d", file_handle);
little_more("\n");
memcpy(params->fname, fname, 10);
params->fd = file_handle;
 
little_more("Request for getting info about file ");
little_more(fname);
little_more("[FSTAT called]...");
retval = send_request(fs_phone, FS_FSTAT, params, share);
if (retval < 0) {
printf("%d", retval);
little_more("\n");
return -1;
}
little_more("OK\n");
params->fd = file_handle;
params->offset = 100;
params->whence = 1; /* from actual position in the file */
 
little_more("Request for seeking after ");
printf("%d", params->offset);
little_more(" bytes inside file ");
little_more(fname);
little_more("...");
retval = send_request(fs_phone, FS_SEEK, params, share);
if (retval < 0) {
printf("%d", retval);
little_more("\n");
return -1;
}
little_more("OK\n");
 
little_more("New file position is: ");
printf("%d", retval);
little_more("\n");
params->nbytes = 100;
little_more("Request for reading ");
printf("%d", params->nbytes);
little_more(" bytes from file ");
little_more(fname);
little_more("...");
retval = send_request(fs_phone, FS_READ, params, share);
if (retval < 0) {
printf("%d", retval);
little_more("\n");
return -1;
}
little_more("OK\n");
printf("%d", retval);
little_more(" bytes was read into buffer\n");
little_more("\nContent of the buffer:\n");
little_more(share);
little_more("\n\n");
params->offset = 0;
params->whence = 0; /* from beginning of the file */
 
little_more("Request for seeking after ");
printf("%d", params->offset);
little_more(" bytes inside file ");
little_more(fname);
little_more("...");
retval = send_request(fs_phone, FS_SEEK, params, share);
if (retval < 0) {
printf("%d", retval);
little_more("\n");
return -1;
}
little_more("OK\n");
little_more("New file position is: ");
printf("%d", retval);
little_more("\n");
params->fd = file_handle;
params->nbytes = 50;
 
little_more("Another request for reading ");
printf("%d", params->nbytes);
little_more(" bytes from file ");
little_more(fname);
little_more("...");
retval = send_request(fs_phone, FS_READ, params, share);
if (retval < 0) {
printf("%d", retval);
little_more("\n");
return -1;
}
little_more("OK\n");
 
printf("%d", retval);
little_more(" bytes was read into buffer\n");
little_more("\nContent of the buffer:\n");
little_more(share);
little_more("\n\n");
 
little_more("Request for closing file ");
little_more(fname);
little_more("...");
retval = send_request(fs_phone, FS_CLOSE, params, share);
if (retval < 0) {
printf("%d", retval);
little_more("\n");
return -1;
}
little_more("OK\n");
 
/*
printf("Request for closing file %s once more...", fname);
retval = send_request(fs_phone, FS_CLOSE, params, share);
if (retval < 0) {
printf("%d\n", retval);
return -1;
}
printf("OK\n");
*/
 
little_more("Request for dropping the connection to the FS...");
retval = send_request(fs_phone, FS_DROP_CONSUMER, params, share);
if (retval < 0) {
printf("%d", retval);
little_more("\n");
return -1;
}
little_more("OK\n");
 
/* Unmapping share area. */
little_more("Unmapping share area...");
retval = munmap(share, size);
if (retval < 0) {
printf("%d", retval);
little_more("\n");
return -1;
}
little_more("OK\n");
little_more("Creating address space area...");
size = ALIGN_UP(BLOCK_SIZE * sizeof(char), PAGE_SIZE);
share = mmap(share, size, AS_AREA_READ | AS_AREA_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0);
if ((int)share < 0){
little_more("As_area_create error: ");
printf("%d");
little_more("\n");
return -1;
}
little_more("OK\n");
 
/* Next connection to the FS. */
little_more("Connecting the task to FS...");
retval = async_req_2(fs_phone, FS_NEW_CONSUMER, task_get_id(), 0, NULL, NULL);
if (retval < 0) {
little_more("FS_NEW_CONSUMER error: ");
printf("%d", retval);
little_more("\n");
return -1;
}
little_more("OK\n");
little_more("Sending memory to FS_SERVICE...");
flags = 0;
flags = AS_AREA_READ | AS_AREA_WRITE;
retval = async_req_3(fs_phone, IPC_M_AS_AREA_SEND, (uintptr_t)share, size, flags, NULL, NULL, NULL);
if (retval < 0) {
printf("%d", retval);
little_more("\n");
return -1;
}
little_more("OK\n");
 
/* We want to work with specified file. */
memcpy(fname, "/kernel/arch", 20);
memcpy(params->fname, fname, 20);
 
little_more("Request for getting info about file ");
little_more(fname);
little_more("[STAT called]...");
retval = send_request(fs_phone, FS_STAT, params, share);
if (retval < 0) {
printf("%d", retval);
little_more("\n");
return -1;
}
little_more("OK\n");
stat_t file_info;
memcpy((void *)(&file_info), share, sizeof(stat_t));
 
little_more("Info about file: ");
little_more(fname);
little_more("\nInode number: ");
printf("%d", file_info.st_ino);
little_more("\nMode: ");
printf("%d", file_info.st_mode);
little_more("\nLinks: ");
printf("%d", file_info.st_nlink);
little_more("\nSize: ");
printf("%d", file_info.st_size);
little_more("\n");
//==================================================================================
while(1)
{
printf("\n\n\n- <stdio.h> calls -\n\n");
printf("What do you want to do?\n");
printf("o - open some file\n");
printf("c - close some file\n");
printf("r - read some file\n");
printf("? ");
char * choice = input_read(1);
switch (choice[0])
{
case 'o':
open_file();
break;
case 'c':
close_file();
break;
case 'r':
read_file();
break;
}
free(choice);
wait_for_char(SPACE_BAR);
printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
}
return 0;
}
 
 
/branches/fs/uspace/libc/include/io/file.h
0,0 → 1,97
/** @addtogroup FileLib
* @{
*/
 
/**
* @file file.h
* @brief The main header for the user library for working with the file system
*/
 
#ifndef _FILE_H
#define _FILE_H
 
#include "../../../fs/const.h"
#include "../../../fs/type.h"
#include "../../../fs/stat.h"
#include "../../../fs/dir.h"
#include "../../../share/message.h"
 
#define F_OK 0x00
#define F_FILE_NOT_FOUND 0x01
#define F_FILE_NOT_OPEN 0x02
#define F_READ_ERROR 0x10
#define F_READ_OVERFLOW 0x11
#define F_SYSTEM_ERROR 0xf0
#define F_IPC_FAILURE 0xf1
#define F_MMAP_FAILURE 0xf2
#define F_COMM_FAILURE 0xf3
 
#define F_ERRTYPE_MASK 0xf0
 
#define F_MODE_READ 0x01
#define F_MODE_WRITE 0x02
#define F_MODE_READ_WRITE F_MODE_READ | F_MODE_WRITE
#define F_MODE_APPEND 0x04
 
/**
*
*/
typedef struct {
char name[30];
unsigned short inode_num;
} dir_item_t;
 
/**
*
*/
typedef struct {
size_t size;
dir_item_t base_info;
void *share;
message_params_t *params;
unsigned int handle;
stat_t stat;
} file_t;
 
static int f_err;
 
/**
* a
*/
dir_item_t * ls(unsigned int * length);
 
/**
*
*/
int chdir(char * new_dir);
 
/**
*
*/
file_t * fopen (char * name, int mode);
 
/**
*
*/
int fstat(file_t * file);
 
/**
*
*/
int fread(file_t * file, void* buffer, unsigned int size);
 
/**
*
*/
int fseek(file_t * file, int offset, int whence);
 
/**
*
*/
int fclose(file_t * file);
 
#endif
 
/**
* }
*/
/branches/fs/uspace/libc/generic/io/file.c
0,0 → 1,344
/** @addtogroup FileLib
* @{
*/
 
/**
* @file file.c
* @brief The user library for working with the file system
*/
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <async.h>
#include <ipc/services.h>
#include <ipc/ipc.h>
#include <sys/mman.h>
#include <io/file.h>
#include <bool.h>
#include <err.h>
#include <align.h>
#include "../../../fs/dir.h"
#include "../../../share/message.h"
#include "../../../share/shared_proto.h"
 
#define CONNECT_SLEEP_INTERVAL 10000
#define CONNECT_SLEEP_TIMEOUT 100000
#define CON_FS_ATTEMPTS 1000
 
/**
*
*/
static int fs_phone;
 
file_t * file_connect();
int file_disconnect(file_t * file);
 
/**
* Connect to the FS task and share memory with it for further data and
* extended memory transfers
*/
file_t * file_connect() {
file_t * result;
size_t size;
void *share = NULL;
int retval;
 
printf("Connecting to the SERVICE_FS...");
if (!connect_to_fs(&fs_phone, CON_FS_ATTEMPTS)) {
printf("Connection to SERVICE_FS was refused\n");
f_err = F_IPC_FAILURE;
return NULL;
}
printf("OK\n");
return F_OK;
printf("Creating address space area...");
size = ALIGN_UP(BLOCK_SIZE * sizeof(char), PAGE_SIZE);
share = mmap(share, size, AS_AREA_READ | AS_AREA_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0);
if ((int)share < 0){
printf("As_area_create error: %d\n", (int)share);
f_err = F_MMAP_FAILURE;
return NULL;
}
printf("OK\n");
 
printf("Connecting the task to FS...");
retval = async_req_2(fs_phone, FS_NEW_CONSUMER, task_get_id(), 0, NULL, NULL);
if (retval < 0) {
printf("FS_NEW_CONSUMER error: %d\n", retval);
f_err = F_COMM_FAILURE;
return NULL;
}
printf("OK\n");
 
printf("Sending memory to FS_SERVICE...");
int flags = 0;
flags = AS_AREA_READ | AS_AREA_WRITE;
retval = async_req_3(fs_phone, IPC_M_AS_AREA_SEND, (uintptr_t)share, size, flags, NULL, NULL, NULL);
if (retval < 0) {
printf("%d\n", retval);
f_err = F_COMM_FAILURE;
return NULL;
}
printf("OK\n");
/* Allocating structure for extended message. */
message_params_t *params;
params = malloc(sizeof(message_params_t));
memset((void*)params, 0, sizeof(message_params_t));
result = malloc(sizeof(file_t));
result->share = share;
result->size = size;
result->params = params;
f_err = F_OK;
return result;
}
 
/**
* Disconnect from the FS task, unsharing memory and freeing the file data structure
*/
int file_disconnect(file_t * file) {
int retval;
printf("Request for dropping the connection to the FS...");
retval = send_request(fs_phone, FS_DROP_CONSUMER, file->params, file->share);
if (retval < 0) {
printf("%d\n", retval);
return -1;
}
printf("OK\n");
/* Unmapping share area. */
printf("Unmapping share area...");
retval = munmap(file->share, file->size);
if (retval < 0) {
printf("%d\n", retval);
return -1;
}
printf("OK\n");
printf("Creating address space area...");
file->size = ALIGN_UP(BLOCK_SIZE * sizeof(char), PAGE_SIZE);
file->share = mmap(file->share, file->size, AS_AREA_READ | AS_AREA_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0);
if ((int)(file->share) < 0){
printf("As_area_create error: %d\n", (int)(file->share));
return -1;
}
printf("OK\n");
 
free(file);
f_err = F_OK;
return F_OK;
}
 
/**
* List contents of the current directory
*/
dir_item_t * ls(unsigned int * length) {
dir_item_t * result;
unsigned short entries_num;
int retval;
 
file_t * shared_file = file_connect();
if (shared_file == NULL) {
return NULL;
}
/* We want lookup our work directory. */
printf("Request for get number of entries...");
retval = send_request(fs_phone, FS_DSUM, shared_file->params, shared_file->share);
if (retval < 0) {
printf("%d\n", retval);
f_err = F_READ_ERROR;
return NULL;
}
printf("OK\n");
printf("Total number of entries: %d\n", retval);
entries_num = retval;
*length = entries_num;
/* File list in working directory. */
printf("File list:\n");
result = malloc(entries_num * sizeof (dir_item_t));
int entry;
for (entry = 0; entry < entries_num; entry++) {
 
shared_file->params->entry_number = entry;
retval = send_request(fs_phone, FS_READENTRY, shared_file->params, shared_file->share);
if (retval < 0) {
printf("%d\n", retval);
f_err = F_READ_ERROR;
return NULL;
}
memcpy(&(result[entry].inode_num), shared_file->share, sizeof(unsigned short));
memcpy(result[entry].name, (void *)(shared_file->share+sizeof(unsigned short)), retval-sizeof(unsigned short));
 
/* Do not show empty entries. */
if (!result[entry].inode_num)
continue;
printf("Inode number: %u\t\t", result[entry].inode_num);
printf("File name: %s\n", result[entry].name);
}
printf("OK\n");
return result;
}
 
/**
* Change the current working directory for the task
*/
int chdir(char * new_dir) {
int retval;
file_t * shared_file = file_connect();
if (shared_file == NULL) {
f_err = F_READ_ERROR;
return F_READ_ERROR;
}
memcpy(shared_file->params->fname, new_dir, 30);
printf("Request for changing the curret directory to %s...", new_dir);
retval = send_request(fs_phone, FS_CHDIR, shared_file->params, shared_file->share);
if (retval < 0) {
printf("%d\n", retval);
f_err = F_READ_ERROR;
return F_READ_ERROR;
}
printf("OK\n");
 
retval = file_disconnect(shared_file);
f_err = F_OK;
return F_OK;
}
 
/**
* Open a file for reading and/or writing
*/
file_t * fopen (char * name, int mode){
int retval;
file_t * file = file_connect();
/* We want to work with the specified file. */
memcpy(file->params->fname, name, 30);
 
printf("Request for opening file %s...", name);
retval = send_request(fs_phone, FS_OPEN, file->params, file->share);
if (retval < 0) {
printf("%d\n", retval);
return NULL;
}
printf("OK\n");
 
file->handle = retval;
printf("Returned file handle...%d\n", file->handle);
return file;
}
 
/**
* Read status information about a file
*/
int fstat(file_t * file) {
int retval;
memcpy(file->params->fname, file->base_info.name, 30);
file->params->fd = file->handle;
 
printf("Request for getting info about file %s[FSTAT called]...", file->params->fname);
retval = send_request(fs_phone, FS_FSTAT, file->params, file->share);
if (retval < 0) {
printf("%d\n", retval);
return -1;
}
memcpy((void *)(&file->stat), file->share, sizeof(stat_t));
 
printf("Info about file: %s\n", file->params->fname);
printf("Inode number: %d\n", file->stat.st_ino);
printf("Mode: %d\n", file->stat.st_mode);
printf("Links: %d\n", file->stat.st_nlink);
printf("Size: %d\n", file->stat.st_size);
printf("OK\n");
f_err = F_OK;
return F_OK;
}
 
/**
* Read data from a file
*/
int fread(file_t * file, void* buffer, unsigned int size){
int retval;
file->params->nbytes = size;
printf("Request for reading %d bytes from file %s...", file->params->nbytes, file->params->fname);
retval = send_request(fs_phone, FS_READ, file->params, file->share);
if (retval < 0) {
printf("%d\n", retval);
return -1;
}
printf("OK\n");
printf("%d bytes was read into buffer\n", retval);
printf("\nContent of the buffer:\n");
printf(file->share);
printf("\n\n");
f_err = F_OK;
return F_OK;
}
 
/**
* Seek to a position within a file
*/
int fseek(file_t * file, int offset, int whence) {
int retval;
file->params->offset = 0;
file->params->whence = 0; /* from beginning of the file */
 
printf("Request for seeking after %d bytes inside file %s...", file->params->offset, file->params->fname);
retval = send_request(fs_phone, FS_SEEK, file->params, file->share);
if (retval < 0) {
printf("%d\n", retval);
return -1;
}
printf("OK\n");
printf("New file position is: %d\n", retval);
f_err = F_OK;
return F_OK;
}
 
/**
* Close a file
*/
int fclose(file_t * file) {
int retval;
printf("Request for closing file %s...", file->params->fname);
retval = send_request(fs_phone, FS_CLOSE, file->params, file->share);
if (retval < 0) {
printf("%d\n", retval);
return -1;
}
printf("OK\n");
if (file != NULL) file_disconnect(file);
f_err = F_OK;
return F_OK;
}
 
/**
* }
*/
/branches/fs/uspace/libc/Makefile
72,7 → 72,8
generic/time.c \
generic/err.c \
generic/stdlib.c \
generic/mman.c
generic/mman.c \
generic/io/file.c
 
ARCH_SOURCES += \
arch/$(ARCH)/src/entry.s \