source: mainline/uspace/lib/libc/generic/io/file.c@ c7509e5

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since c7509e5 was 00acd66, checked in by Jakub Jermar <jakub@…>, 18 years ago

New, better-structured, directory layout for uspace.

  • Property mode set to 100644
File size: 6.9 KB
Line 
1/*
2 * Copyright (c) 2007 Michal Konopa
3 * Copyright (c) 2007 Martin Jelen
4 * Copyright (c) 2007 Peter Majer
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * - Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * - Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * - The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31/** @addtogroup libc
32 * @{
33 */
34
35/**
36 * @file file.c
37 * @brief The user library for working with the file system
38 */
39
40#include <stdio.h>
41#include <stdlib.h>
42#include <string.h>
43#include <unistd.h>
44#include <async.h>
45#include <ipc/services.h>
46#include <ipc/ipc.h>
47#include <sys/mman.h>
48#include <io/file.h>
49#include <bool.h>
50#include <err.h>
51#include <align.h>
52#include "../../../fs/dir.h"
53#include "../../../share/message.h"
54#include "../../../share/shared_proto.h"
55
56#define CONNECT_SLEEP_INTERVAL 10000
57#define CONNECT_SLEEP_TIMEOUT 100000
58
59/**
60*
61*/
62static int fs_phone;
63
64static file_t *file_connect();
65static int file_disconnect(file_t *file);
66
67/**
68 * Connect to the FS task and share memory with it for further data and
69 * extended memory transfers
70 */
71file_t *file_connect() {
72 file_t *result;
73
74 size_t size;
75 void *share = NULL;
76 int retval;
77
78 size = ALIGN_UP(BLOCK_SIZE * sizeof(char), PAGE_SIZE);
79 share = mmap(share, size, AS_AREA_READ | AS_AREA_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0);
80 if ((int) share < 0) {
81 f_err = F_MMAP_FAILURE;
82 return NULL;
83 }
84
85 retval = async_req_2(fs_phone, FS_NEW_CONSUMER, task_get_id(), 0, NULL, NULL);
86 if (retval < 0) {
87 f_err = F_COMM_FAILURE;
88 return NULL;
89 }
90
91 int flags = 0;
92 flags = AS_AREA_READ | AS_AREA_WRITE;
93 retval = async_req_3(fs_phone, IPC_M_AS_AREA_SEND, (uintptr_t)share, size, flags, NULL, NULL, NULL);
94 if (retval < 0) {
95 f_err = F_COMM_FAILURE;
96 return NULL;
97 }
98
99 /* Allocating structure for extended message. */
100 message_params_t *params = malloc(sizeof(message_params_t));
101 memset((void*) params, 0, sizeof(message_params_t));
102
103 result = malloc(sizeof(file_t));
104 result->share = share;
105 result->size = size;
106 result->params = params;
107
108 f_err = F_OK;
109 return result;
110}
111
112/**
113 * Disconnect from the FS task, unsharing memory and freeing the file data structure
114 */
115int file_disconnect(file_t *file) {
116 int retval = send_request(fs_phone, FS_DROP_CONSUMER, file->params, file->share);
117 if (retval < 0)
118 return -1;
119
120 /* Unmapping share area. */
121 retval = munmap(file->share, file->size);
122 if (retval < 0)
123 return -1;
124
125 file->size = ALIGN_UP(BLOCK_SIZE * sizeof(char), PAGE_SIZE);
126 file->share = mmap(file->share, file->size, AS_AREA_READ | AS_AREA_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0);
127 if ((int) (file->share) < 0)
128 return -1;
129
130 free(file);
131 f_err = F_OK;
132 return F_OK;
133}
134
135/**
136 * List contents of the current directory
137 */
138dir_item_t *ls(unsigned int *length) {
139 dir_item_t *result;
140 unsigned short entries_num;
141
142 file_t *shared_file = file_connect();
143 if (shared_file == NULL)
144 return NULL;
145
146 /* We want lookup our work directory. */
147 retval = send_request(fs_phone, FS_DSUM, shared_file->params, shared_file->share);
148 if (retval < 0) {
149 f_err = F_READ_ERROR;
150 return NULL;
151 }
152
153 entries_num = retval;
154 *length = entries_num;
155
156 result = malloc(entries_num * sizeof (dir_item_t));
157
158 int entry;
159 for (entry = 0; entry < entries_num; entry++) {
160 shared_file->params->entry_number = entry;
161 retval = send_request(fs_phone, FS_READENTRY, shared_file->params, shared_file->share);
162 if (retval < 0) {
163 f_err = F_READ_ERROR;
164 return NULL;
165 }
166
167 memcpy(&(result[entry].inode_num), shared_file->share, sizeof(unsigned short));
168 memcpy(result[entry].name, (void *)(shared_file->share+sizeof(unsigned short)), retval-sizeof(unsigned short));
169
170 /* Do not show empty entries. */
171 if (!result[entry].inode_num)
172 continue;
173
174 }
175 return result;
176}
177
178/**
179 * Change the current working directory for the task
180 */
181int chdir(char * new_dir)
182{
183 file_t *shared_file = file_connect();
184
185 if (shared_file == NULL) {
186 f_err = F_READ_ERROR;
187 return F_READ_ERROR;
188 }
189 memcpy(shared_file->params->fname, new_dir, 30);
190
191 int retval = send_request(fs_phone, FS_CHDIR, shared_file->params, shared_file->share);
192 if (retval < 0) {
193 f_err = F_READ_ERROR;
194 return F_READ_ERROR;
195 }
196
197 retval = file_disconnect(shared_file);
198 f_err = F_OK;
199 return F_OK;
200}
201
202/**
203 * Open a file for reading and/or writing
204 */
205file_t *fopen(char *name, int mode)
206{
207 file_t *file = file_connect();
208
209 /* We want to work with the specified file. */
210 memcpy(file->params->fname, name, 30);
211
212 int retval = send_request(fs_phone, FS_OPEN, file->params, file->share);
213 if (retval < 0)
214 return NULL;
215
216 file->handle = retval;
217
218 return file;
219}
220
221/**
222 * Read status information about a file
223 */
224int fstat(file_t *file)
225{
226 memcpy(file->params->fname, file->base_info.name, 30);
227 file->params->fd = file->handle;
228
229 int retval = send_request(fs_phone, FS_FSTAT, file->params, file->share);
230 if (retval < 0)
231 return -1;
232
233 memcpy((void *)(&file->stat), file->share, sizeof(stat_t));
234
235 f_err = F_OK;
236 return F_OK;
237}
238
239/**
240 * Read data from a file
241 */
242int fread(file_t *file, void* buffer, unsigned int size)
243{
244 file->params->nbytes = size;
245
246 int retval = send_request(fs_phone, FS_READ, file->params, file->share);
247 if (retval < 0)
248 return -1;
249
250 f_err = F_OK;
251 return F_OK;
252}
253
254/**
255 * Seek to a position within a file
256 */
257int fseek(file_t *file, int offset, int whence)
258{
259 file->params->offset = 0;
260 file->params->whence = 0; /* from beginning of the file */
261
262 int retval = send_request(fs_phone, FS_SEEK, file->params, file->share);
263 if (retval < 0)
264 return -1;
265
266 f_err = F_OK;
267 return F_OK;
268}
269
270/**
271 * Close a file
272 */
273int fclose(file_t *file)
274{
275 int retval = send_request(fs_phone, FS_CLOSE, file->params, file->share);
276 if (retval < 0)
277 return -1;
278
279 if (file != NULL)
280 file_disconnect(file);
281
282 f_err = F_OK;
283 return F_OK;
284}
285
286/**
287 *@}
288 */
Note: See TracBrowser for help on using the repository browser.