00001 /*! \file files.c 00002 This file contains all the file's related functions. 00003 */ 00004 00005 #include "files.h" 00006 00007 /*! \brief Wait for a file to appear. 00008 \param file_name Name of the file. 00009 \param period The function test if the file exists periodically. If the file does not exist, then the process is put 00010 to sleep for a certain amount of time, and then the function tests the file existence again ... and so on. Between 00011 each test, the process is put to sleep for 'period' seconds. 00012 \param stop_file If the file that name is defined by 'stop_file' exists, then the function exists and returns 1. 00013 \return If the file represented by 'file_name' exists, the function return 0. If the file represented by 00014 'stop_file' exists, the the function returns 1. 00015 \warning This function uses the system call access() to test the existence of a file. According to the documentation, 00016 this system call can be interrupted by a signal. But in this case the return value is -1, which is also the 00017 return value if the file does not exist. Therefore we do not have to perform any special action in case the 00018 system call is interrupted ... we just try again. 00019 */ 00020 00021 int wait_for_file (char* file_name, int period, char* stop_file) 00022 { 00023 while (access (file_name, F_OK) == -1) 00024 { 00025 if (stop_file != NULL) 00026 { 00027 if (access (stop_file, F_OK) == 0) { return 1; } 00028 } 00029 00030 sleep (period); 00031 } 00032 return 0; 00033 } 00034 00035 /*! \example test_wait_for_file.c 00036 This file shows how to use the function wait_for_file(). 00037 */ 00038 00039 00040 /*! \brief Wait for a file (within a list of files) to exist. 00041 \param file_names This variable represents the list of file names to test. It is an array of strings, each string 00042 represents a file name. The last element of the list MUST be set to NULL. 00043 \param period The function test if the file exists periodically. If the file does not exist, then the process is put 00044 to sleep for a certain amount of time, and then the function tests the file existence again ... and so on. Between 00045 each test, the process is put to sleep for 'period' seconds. 00046 \param stop_file If the file that name is defined by 'stop_file' exists, then the function exists and returns 1. 00047 \return If one of the files specified in the list of files exists, the function returns a non NULL pointer that points 00048 a the name of the file. If the file represented by 'stop_file' exists, the the function returns NULL. 00049 \warning The last element of the list of file names MUST be set to NULL. If you want to wait on 3 files, then the 00050 variable 'file_names' must be an array of 4 elements: the 3 file names and the last NULL pointer. 00051 */ 00052 00053 char* wait_for_multiple_file (char **file_names, int period, char* stop_file) 00054 { 00055 char *name; 00056 int pos; 00057 00058 while (1==1) 00059 { 00060 pos = 0; 00061 name = file_names[pos]; 00062 00063 while (name != NULL) 00064 { 00065 if (access (name, F_OK) == 0) { return name; } 00066 pos++; 00067 name = file_names[pos]; 00068 } 00069 00070 if (stop_file != NULL) 00071 { if (access (stop_file, F_OK) == 0) { break; } } 00072 00073 sleep(period); 00074 } 00075 00076 return NULL; 00077 } 00078 00079 /*! \example test_wait_for_multiple_files.c 00080 This file shows how to use the function wait_for_multiple_file. 00081 */ 00082 00083 /*! \brief Load the content of a file into an in-memory buffer. 00084 \param file_name Pointer to a zero terminated file that represents the name of the file to load.. 00085 \param buff Pointer to a pointer that will be used to save the file's content. 00086 \return If the function succed, the function returns a positive interger that represents the number of bytes extracted 00087 from the file. If the function failes, then it returns a negative integer. This integer could be: 00088 <UL> 00089 <li>FILES_UTIL_MALLOC_ERR 00090 <li>FILES_UTIL_READ_ERR 00091 </UL> 00092 \warning The memory pointed by 'buff' has been allocated within the function, therefore you must free it yourself 00093 (using free()). 00094 */ 00095 00096 int read_file (char *file_name, char **buff) 00097 { 00098 int c, lu, taille; 00099 FILE *fd; 00100 00101 fd = fopen (file_name, "r"); 00102 if (fd == NULL) { return FILES_UTIL_OPEN_ERR; } 00103 00104 00105 taille = FILES_UTIL_INIT_BUFF_SIZE; 00106 *buff = (char*)malloc(taille); 00107 if (*buff == NULL) 00108 { 00109 fclose(fd); 00110 return FILES_UTIL_MALLOC_ERR; 00111 } 00112 00113 lu=0; 00114 c = fgetc(fd); 00115 00116 while (feof(fd) == 0) 00117 { 00118 if (c == EOF) 00119 { 00120 fclose(fd); 00121 return FILES_UTIL_READ_ERR; 00122 } 00123 lu++; 00124 00125 while (lu > (taille-1)) 00126 { 00127 taille *= 2; 00128 *buff = (char*)realloc((void*)(*buff), taille); 00129 if (*buff == NULL) 00130 { 00131 fclose(fd); 00132 return FILES_UTIL_MALLOC_ERR; 00133 } 00134 } 00135 00136 *((*buff) + (lu-1)) = (char)c; 00137 c = fgetc(fd); 00138 } 00139 *((*buff) + lu) = '\0'; 00140 00141 fclose(fd); 00142 return lu; 00143 } 00144 00145 /*! \example test_read_file.c 00146 This file shows how to use the function read_file(). 00147 */ 00148 00149 /*! \brief Set the timeout file that contains the current number of seconds since January 1970 00:00:00. 00150 \param filename Pointer to a zero terminated string of characters that represents the path to the file. 00151 \return The function returns one of the following values: 00152 <UL> 00153 <li>SET_TIMEOUT_FILE_OPEN_ERROR: Can not open the target file 'filename'. 00154 <li>SET_TIMEOUT_FILE_WRITE_ERROR: Error while writing in the target file. 00155 <li>SET_TIMEOUT_FILE_OK: The function succed. 00156 </UL> 00157 */ 00158 00159 int set_timeout_file (char *filename) 00160 { 00161 time_t current_time; 00162 FILE *fd; 00163 int cr; 00164 00165 fd = fopen(filename, "w"); 00166 if (fd == NULL) { return SET_TIMEOUT_FILE_OPEN_ERROR; } 00167 00168 current_time = time(NULL); 00169 00170 cr = fwrite ((void*)¤t_time, sizeof(time_t), 1, fd); 00171 if (cr != 1) 00172 { 00173 fclose (fd); 00174 return SET_TIMEOUT_FILE_WRITE_ERROR; 00175 } 00176 00177 fclose (fd); 00178 return SET_TIMEOUT_FILE_OK; 00179 } 00180 00181 /*! \example test_timeout_file.c 00182 This file shows how to use the functions set_timeout_file() and test_timeout_file(). 00183 */ 00184 00185 /*! \brief Look at a <i>timeout file</i> to see if the calling process should wait or go ahead. 00186 \param filename Pointer to a zero terminated string of characters that represents the timeout file. 00187 \param timeout Integer value that represents the timeout in seconds. 00188 \return The function returns one of the following values: 00189 <UL> 00190 <li>TEST_TIMEOUT_FILE_TIMEOUT_ELLAPSED: The timeout is passed. 00191 <li>TEST_TIMEOUT_FILE_READ_ERROR: An error occured while reading the timeout file. 00192 <li>TEST_TIMEOUT_FILE_TIMEOUT_NOT_ELLAPSED: The timeout is not passed yet. 00193 <li>TEST_TIMEOUT_FILE_UNLINK_FAILED: An error occured while removing the timeout file. 00194 </UL> 00195 \warning The timeout file should have been set by using the function set_timeout_file(). 00196 */ 00197 00198 int test_timeout_file (char *filename, int timeout) 00199 { 00200 time_t current_time, file_time, delta; 00201 FILE *fd; 00202 int cr; 00203 00204 /* ============================================= */ 00205 /* Try to open the timeout file - If it does not */ 00206 /* exist, it means that there was no timeout ... */ 00207 /* ============================================= */ 00208 00209 fd = fopen(filename, "r"); 00210 if (fd == NULL) { return TEST_TIMEOUT_FILE_TIMEOUT_ELLAPSED; } 00211 00212 /* ============================================= */ 00213 /* Read timestamp written into the file */ 00214 /* ============================================= */ 00215 00216 cr = fread ((void*)&file_time, sizeof(time_t), 1, fd); 00217 if (cr != 1) 00218 { 00219 fclose (fd); 00220 return TEST_TIMEOUT_FILE_READ_ERROR; 00221 } 00222 current_time = time(NULL); 00223 00224 /* ============================================= */ 00225 /* Calculate the ellapsed time */ 00226 /* ============================================= */ 00227 00228 delta = current_time - file_time; 00229 if (delta < timeout) 00230 { 00231 fclose (fd); 00232 return TEST_TIMEOUT_FILE_TIMEOUT_NOT_ELLAPSED; 00233 } 00234 00235 fclose (fd); 00236 00237 /* ============================================= */ 00238 /* Delete timeout file if the timeout expired */ 00239 /* ============================================= */ 00240 00241 if (unlink (filename) != 0) { return TEST_TIMEOUT_FILE_UNLINK_FAILED; } 00242 00243 return TEST_TIMEOUT_FILE_TIMEOUT_ELLAPSED; 00244 } 00245 00246 /*! \example test_timeout_file.c 00247 This file shows how to use the functions set_timeout_file() and test_timeout_file(). 00248 */ 00249 00250 00251 00252 /*! \brief Extract the base name of a given file name. 00253 \param src Pointer to a zero terminated string of characters that represents the name of the file. 00254 \param dst Pointer to a memory location that will be sued to store a zero terminated string of 00255 characters that is the base name of the file. 00256 \warning No test is done regarding the size of the memory chunck pointed by dst. It is your responsability 00257 to allocate enough memory for the resulting string of characters! 00258 */ 00259 00260 void basename (char *src, char *dst) 00261 { 00262 char *pt; 00263 00264 pt = strrchr (src, '/'); 00265 if (pt == NULL) { pt = src; } 00266 else { pt += 1; } 00267 00268 strcpy (dst, pt); 00269 } 00270 00271