Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Destructor should be virtual.
[simgrid.git] / src / msg / msg_io.c
1 /* Copyright (c) 2004-2013. The SimGrid Team.
2  * All rights reserved.                                                       */
3
4 /* This program is free software; you can redistribute it and/or modify it
5  * under the terms of the license (GNU LGPL) which comes with this package.   */
6
7 #include "msg_private.h"
8 #include "xbt/log.h"
9
10 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(msg_io, msg,
11                                 "Logging specific to MSG (io)");
12
13 /** @addtogroup msg_file_management
14  * \htmlonly <!-- DOXYGEN_NAVBAR_LABEL="Files" --> \endhtmlonly
15  * (#msg_file_t) and the functions for managing it.
16  *
17  *  \see #msg_file_t
18  */
19
20 /********************************* File **************************************/
21 void __MSG_file_get_info(msg_file_t fd){
22   xbt_dynar_t info = simcall_file_get_info(fd->simdata->smx_file);
23   sg_size_t *psize;
24
25   fd->info->content_type = xbt_dynar_pop_as(info, char *);
26   fd->info->storage_type = xbt_dynar_pop_as(info, char *);
27   fd->info->storageId = xbt_dynar_pop_as(info, char *);
28   fd->info->mount_point = xbt_dynar_pop_as(info, char *);
29   psize = xbt_dynar_pop_as(info, sg_size_t*);
30   fd->info->size = *psize;
31   xbt_free(psize);
32   xbt_dynar_free_container(&info);
33 }
34
35 /** \ingroup msg_file_management
36  *
37  * \brief Set the user data of a #msg_file_t.
38  *
39  * This functions checks whether some data has already been associated to \a file
40    or not and attach \a data to \a file if it is possible.
41  */
42 msg_error_t MSG_file_set_data(msg_file_t fd, void *data)
43 {
44   SIMIX_file_set_data(fd->simdata->smx_file,data);
45
46   return MSG_OK;
47 }
48
49 /** \ingroup msg_file_management
50  *
51  * \brief Return the user data of a #msg_file_t.
52  *
53  * This functions checks whether \a file is a valid pointer or not and return
54    the user data associated to \a file if it is possible.
55  */
56 void *MSG_file_get_data(msg_file_t fd)
57 {
58   return SIMIX_file_get_data(fd->simdata->smx_file);
59 }
60
61 /** \ingroup msg_file_management
62  * \brief Display information related to a file descriptor
63  *
64  * \param fd is a the file descriptor
65  */
66
67 void MSG_file_dump (msg_file_t fd){
68 //   THROW_UNIMPLEMENTED;
69   /* Update the cached information first */
70   __MSG_file_get_info(fd);
71   XBT_INFO("File Descriptor information:\n"
72            "\t\tFull name: '%s'\n"
73            "\t\tSize: %llu\n"
74            "\t\tMount point: '%s'\n"
75            "\t\tStorage Id: '%s'\n"
76            "\t\tStorage Type: '%s'\n"
77            "\t\tContent Type: '%s'",
78            fd->fullname, fd->info->size, fd->info->mount_point,
79            fd->info->storageId, fd->info->storage_type,
80            fd->info->content_type);
81 }
82
83 /** \ingroup msg_file_management
84  * \brief Read a file
85  *
86  * \param size of the file to read
87  * \param fd is a the file descriptor
88  * \return the number of bytes successfully read
89  */
90 sg_size_t MSG_file_read(msg_file_t fd, sg_size_t size)
91 {
92   return simcall_file_read(fd->simdata->smx_file, size);
93 }
94
95 /** \ingroup msg_file_management
96  * \brief Write into a file
97  *
98  * \param size of the file to write
99  * \param fd is a the file descriptor
100  * \return the number of bytes successfully write
101  */
102 sg_size_t MSG_file_write(msg_file_t fd, sg_size_t size)
103 {
104   return simcall_file_write(fd->simdata->smx_file, size);
105 }
106
107 /** \ingroup msg_file_management
108  * \brief Opens the file whose name is the string pointed to by path
109  *
110  * \param mount is the mount point where find the file is located
111  * \param fullname is the file location on the storage
112  * \param data user data to attach to the file
113  *
114  * \return An #msg_file_t associated to the file
115  */
116 msg_file_t MSG_file_open(const char* mount, const char* fullname, void* data)
117 {
118   msg_file_t file = xbt_new(s_msg_file_t,1);
119   file->fullname = xbt_strdup(fullname);
120   file->simdata = xbt_new0(s_simdata_file_t,1);
121   file->info = xbt_new0(s_msg_file_info_t,1);
122   file->simdata->smx_file = simcall_file_open(mount, fullname);
123   SIMIX_file_set_data(file->simdata->smx_file, data);
124   return file;
125 }
126
127 /** \ingroup msg_file_management
128  * \brief Close the file
129  *
130  * \param fd is the file to close
131  * \return 0 on success or 1 on error
132  */
133 int MSG_file_close(msg_file_t fd)
134 {
135   int res = simcall_file_close(fd->simdata->smx_file);
136   free(fd->fullname);
137   xbt_free(fd->simdata);
138   xbt_free(fd->info);
139   xbt_free(fd);
140   return res;
141 }
142
143 /** \ingroup msg_file_management
144  * \brief Unlink the file pointed by fd
145  *
146  * \param fd is the file descriptor (#msg_file_t)
147  * \return 0 on success or 1 on error
148  */
149 int MSG_file_unlink(msg_file_t fd)
150 {
151   int res = simcall_file_unlink(fd->simdata->smx_file);
152   free(fd->fullname);
153   xbt_free(fd->simdata);
154   xbt_free(fd->info);
155   xbt_free(fd);
156   return res;
157 }
158
159 /** \ingroup msg_file_management
160  * \brief Return the size of a file
161  *
162  * \param fd is the file descriptor (#msg_file_t)
163  * \return the size of the file (as a sg_size_t)
164  */
165 sg_size_t MSG_file_get_size(msg_file_t fd){
166   return simcall_file_get_size(fd->simdata->smx_file);
167 }
168
169 /** \ingroup msg_file_management
170  * \brief Search for file
171  *
172  * \param mount is the mount point where find the file is located
173  * \param path the file regex to find
174  * \return a xbt_dict_t of file where key is the name of file and the
175  * value the msg_stat_t corresponding to the key
176  */
177 xbt_dict_t MSG_file_ls(const char *mount, const char *path)
178 {
179   xbt_assert(path,"You must set path");
180   int size = strlen(path);
181   if(size && path[size-1] != '/')
182   {
183     char *new_path = bprintf("%s/",path);
184     XBT_DEBUG("Change '%s' for '%s'",path,new_path);
185     xbt_dict_t dict = simcall_file_ls(mount, new_path);
186     xbt_free(new_path);
187     return dict;
188   }
189
190   return simcall_file_ls(mount, path);
191 }
192
193 /*
194  * Set the file position indicator in the msg_file_t by adding offset bytes
195  * to the position specified by whence (either SEEK_SET, SEEK_CUR, or SEEK_END).
196  */
197 msg_error_t MSG_file_seek (msg_file_t fd, sg_size_t offset, int whence)
198 {
199   THROW_UNIMPLEMENTED;
200   return MSG_OK;
201 }
202
203 /********************************* Storage **************************************/
204
205 /** @addtogroup msg_storage_management
206  * \htmlonly <!-- DOXYGEN_NAVBAR_LABEL="Storages" --> \endhtmlonly
207  * (#msg_storage_t) and the functions for managing it.
208  *
209  */
210
211 msg_storage_t __MSG_storage_create(smx_storage_t storage)
212 {
213   const char *name = SIMIX_storage_get_name(storage);
214   msg_storage_priv_t storage_private = xbt_new0(s_msg_storage_priv_t, 1);
215   xbt_lib_set(storage_lib,name,MSG_STORAGE_LEVEL,storage_private);
216   return xbt_lib_get_elm_or_null(storage_lib, name);
217 }
218
219 /*
220  * \brief Destroys a storage (internal call only)
221  */
222 void __MSG_storage_destroy(msg_storage_priv_t storage) {
223
224   free(storage);
225 }
226
227 /** \ingroup msg_storage_management
228  *
229  * \brief Returns the name of the #msg_storage_t.
230  *
231  * This functions checks whether a storage is a valid pointer or not and return its name.
232  */
233 const char *MSG_storage_get_name(msg_storage_t storage) {
234   xbt_assert((storage != NULL), "Invalid parameters");
235   return SIMIX_storage_get_name(storage);
236 }
237
238 /** \ingroup msg_storage_management
239  * \brief Returns the free space size of a storage element
240  * \param name the name of a storage
241  * \return the free space size of the storage element (as a sg_size_t)
242  */
243 sg_size_t MSG_storage_get_free_size(const char* name){
244   return simcall_storage_get_free_size(name);
245 }
246
247 /** \ingroup msg_storage_management
248  * \brief Returns the used space size of a storage element
249  * \param name the name of a storage
250  * \return the used space size of the storage element (as a sg_size_t)
251  */
252 sg_size_t MSG_storage_get_used_size(const char* name){
253   return simcall_storage_get_used_size(name);
254 }
255
256 /** \ingroup msg_storage_management
257  * \brief Returns a xbt_dict_t consisting of the list of properties assigned to this storage
258  * \param storage a storage
259  * \return a dict containing the properties
260  */
261 xbt_dict_t MSG_storage_get_properties(msg_storage_t storage)
262 {
263   xbt_assert((storage != NULL), "Invalid parameters (storage is NULL)");
264   return (simcall_storage_get_properties(storage));
265 }
266
267 /** \ingroup msg_storage_management
268  * \brief Change the value of a given storage property
269  *
270  * \param storage a storage
271  * \param name a property name
272  * \param value what to change the property to
273  * \param free_ctn the freeing function to use to kill the value on need
274  */
275 void MSG_storage_set_property_value(msg_storage_t storage, const char *name, char *value,void_f_pvoid_t free_ctn) {
276   xbt_dict_set(MSG_storage_get_properties(storage), name, value,free_ctn);
277 }
278
279 /** \ingroup msg_storage_management
280  * \brief Finds a msg_storage_t using its name.
281  * \param name the name of a storage
282  * \return the corresponding storage
283  */
284 msg_storage_t MSG_storage_get_by_name(const char *name)
285 {
286   return (msg_storage_t) xbt_lib_get_elm_or_null(storage_lib,name);
287 }
288
289 /** \ingroup msg_storage_management
290  * \brief Returns a dynar containing all the storage elements declared at a given point of time
291  *
292  */
293 xbt_dynar_t MSG_storages_as_dynar(void) {
294
295   xbt_lib_cursor_t cursor;
296   char *key;
297   void **data;
298   xbt_dynar_t res = xbt_dynar_new(sizeof(msg_storage_t),NULL);
299
300   xbt_lib_foreach(storage_lib, cursor, key, data) {
301     if(routing_get_network_element_type(key) == MSG_STORAGE_LEVEL) {
302       xbt_dictelm_t elm = xbt_dict_cursor_get_elm(cursor);
303       xbt_dynar_push(res, &elm);
304     }
305   }
306
307   return res;
308 }
309
310 /** \ingroup msg_storage_management
311  *
312  * \brief Set the user data of a #msg_storage_t.
313  * This functions checks whether some data has already been associated to \a storage
314    or not and attach \a data to \a storage if it is possible.
315  */
316 msg_error_t MSG_storage_set_data(msg_storage_t storage, void *data)
317 {
318   SIMIX_storage_set_data(storage,data);
319
320   return MSG_OK;
321 }
322
323 /** \ingroup msg_host_management
324  *
325  * \brief Returns the user data of a #msg_storage_t.
326  *
327  * This functions checks whether \a storage is a valid pointer or not and returns
328    the user data associated to \a storage if it is possible.
329  */
330 void *MSG_storage_get_data(msg_storage_t storage)
331 {
332   return SIMIX_storage_get_data(storage);
333 }
334
335 /** \ingroup msg_storage_management
336  *
337  * \brief Returns the content (file list) of a #msg_storage_t.
338  * \param storage a storage
339  * \return The content of this storage element as a dict (full path file => size)
340  */
341 xbt_dict_t MSG_storage_get_content(msg_storage_t storage)
342 {
343   return SIMIX_storage_get_content(storage);
344 }
345
346 sg_size_t MSG_storage_get_size(msg_storage_t storage)
347 {
348   return SIMIX_storage_get_size(storage);
349 }
350
351 /*
352  * Rename the file in the contents of its associated storage.
353  */
354 msg_error_t MSG_storage_file_rename(msg_storage_t storage, const char* src,  const char* dest)
355 {
356   simcall_storage_file_rename(storage, src, dest);
357   return MSG_OK;
358 }
359
360 /*
361  * Move a file to another location. Depending on the values of dest, dest, mount,
362  * and fullname, this move can be local or remote and, within a host, on the same
363  * mounted disk or between mounted disks.
364  *
365  */
366 msg_error_t MSG_storage_file_move (msg_file_t fd, msg_host_t dest, char* mount, char* fullname)
367 {
368   THROW_UNIMPLEMENTED;
369   return MSG_OK;
370 }