Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2248 → Rev 2433

/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 \