TR181-XPON  1.4.0
TR-181 PON manager.
file_utils.c File Reference
#include "file_utils.h"
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "xpon_trace.h"

Go to the source code of this file.

Macros

#define _GNU_SOURCE
 
#define LINE_LEN   256
 

Functions

static bool rename_file (const char *const oldpath, const char *const newpath)
 
static bool check_file_has_value (const char *const path, const char *const value, bool *has_value)
 
bool write_file (const char *const path, const char *const value)
 
bool read_first_line_from_file (const char *const path, char *line, size_t len)
 

Macro Definition Documentation

◆ _GNU_SOURCE

#define _GNU_SOURCE

To avoid following error: file_utils.c:25:8: error: implicit declaration of function ‘fdatasync’ [-Werror=implicit-function-declaration]

Definition at line 71 of file file_utils.c.

◆ LINE_LEN

#define LINE_LEN   256

Definition at line 84 of file file_utils.c.

Function Documentation

◆ check_file_has_value()

static bool check_file_has_value ( const char *const  path,
const char *const  value,
bool *  has_value 
)
static

Set has_value to true if file path has value value as contents.

Parameters
[in]pathfile path
[in]valuefunction must check if path has value as contents
[in,out]has_valuefunction sets this parameter to true if path has value as contents
Returns
true on success, else false

Definition at line 114 of file file_utils.c.

115  {
116 
117  char line[LINE_LEN] = { 0 };
118  if(!read_first_line_from_file(path, line, LINE_LEN)) {
119  return false;
120  }
121  SAH_TRACEZ_DEBUG2(ME, "line='%s' (%zd) value='%s' (%zd)", line, strlen(line),
122  value, strlen(value));
123 
124  const size_t line_len = strlen(line);
125  const size_t value_len = strlen(value);
126  if(line_len != value_len) {
127  *has_value = false;
128  return true;
129  }
130 
131  if(strncmp(line, value, strlen(value)) == 0) {
132  SAH_TRACEZ_DEBUG2(ME, "file already has %s", value);
133  *has_value = true;
134  } else {
135  SAH_TRACEZ_DEBUG2(ME, "line='%s' != value='%s'", line, value);
136  }
137  return true;
138 }
#define LINE_LEN
Definition: file_utils.c:84
bool read_first_line_from_file(const char *const path, char *line, size_t len)
Definition: file_utils.c:212
#define SAH_TRACEZ_DEBUG2(zone, format,...)
Definition: xpon_trace.h:127
#define ME
Definition: xpon_trace.h:78
Here is the call graph for this function:
Here is the caller graph for this function:

◆ read_first_line_from_file()

bool read_first_line_from_file ( const char *const  path,
char *  line,
size_t  len 
)

Read the first line from a file into a buffer passed by caller.

Parameters
[in]pathfile path
[in,out]linefunction reads 1st line from path and puts it in this parameter
[in]lenlength of line
Returns
true on success, else false

Definition at line 212 of file file_utils.c.

212  {
213  FILE* f = fopen(path, "r");
214  if(!f) {
215  SAH_TRACEZ_ERROR(ME, "Failed to open %s: %s", path, strerror(errno));
216  return false;
217  }
218  bool rv = true;
219  if(!fgets(line, (int) len, f)) {
220  SAH_TRACEZ_ERROR(ME, "Failed to read from %s", path);
221  rv = false;
222  }
223  if(fclose(f) == EOF) {
224  SAH_TRACEZ_ERROR(ME, "Failed to close %s: %s", path, strerror(errno));
225  }
226  return rv;
227 }
Here is the caller graph for this function:

◆ rename_file()

static bool rename_file ( const char *const  oldpath,
const char *const  newpath 
)
static

Definition at line 86 of file file_utils.c.

86  {
87  int fd = 0;
88  if(rename(oldpath, newpath) == -1) {
89  SAH_TRACEZ_ERROR(ME, "Failed to rename %s to %s: %s", oldpath, newpath,
90  strerror(errno));
91  return false;
92  }
93  if((fd = open(newpath, O_RDWR)) == -1) {
94  SAH_TRACEZ_ERROR(ME, "Failed to open %s: %s", newpath, strerror(errno));
95  return false;
96  }
97  if(fdatasync(fd) == -1) {
98  SAH_TRACEZ_ERROR(ME, "Failed to sync %s: %s", newpath, strerror(errno));
99  }
100  close(fd);
101  return true;
102 }
Here is the caller graph for this function:

◆ write_file()

bool write_file ( const char *const  path,
const char *const  value 
)

Write the string value to the file path.

Parameters
[in]pathfile path
[in]valuevalue to write to path

If path already exists and has value as contents, the function immediately returns true to avoid an unneeded write.

The function first writes the value to the file path with ".tmp" appended. Then it renames the file to path.

Returns
true on success, else false

Avoid writing the file if the file already exists and already has the value of the parameter 'value' as contents.

Definition at line 154 of file file_utils.c.

154  {
155 
156  SAH_TRACEZ_DEBUG2(ME, "path='%s' value='%s'", path, value);
157 
158  const size_t value_len = strlen(value);
159  if(value_len >= LINE_LEN) {
160  SAH_TRACEZ_ERROR(ME, "strlen(value) = %zd >= %d", value_len, LINE_LEN);
161  return false;
162  }
167  if(access(path, F_OK) == 0) {
168  SAH_TRACEZ_DEBUG2(ME, "%s already exists", path);
169  bool has_value = false;
170  if((check_file_has_value(path, value, &has_value) == true) && has_value) {
171  return true;
172  }
173  }
174 
175  char tmpfile[256];
176  if(snprintf(tmpfile, 256, "%s.tmp", path) < 0) {
177  SAH_TRACEZ_ERROR(ME, "%s: failed to create path with .tmp", path);
178  return false;
179  }
180 
181  FILE* f = fopen(tmpfile, "w");
182  if(!f) {
183  SAH_TRACEZ_ERROR(ME, "Failed to open %s: %s", tmpfile, strerror(errno));
184  return false;
185  }
186 
187  bool rv = true;
188  if(fputs(value, f) == EOF) {
189  SAH_TRACEZ_ERROR(ME, "Failed to write to %s", tmpfile);
190  rv = false;
191  }
192 
193  if(fclose(f) == EOF) {
194  SAH_TRACEZ_ERROR(ME, "Failed to close %s: %s", tmpfile, strerror(errno));
195  }
196  if(!rv) {
197  return false;
198  }
199  return rename_file(tmpfile, path);
200 }
static bool check_file_has_value(const char *const path, const char *const value, bool *has_value)
Definition: file_utils.c:114
static bool rename_file(const char *const oldpath, const char *const newpath)
Definition: file_utils.c:86
Here is the call graph for this function:
Here is the caller graph for this function: