OpenOCD
helper/fileio.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 /***************************************************************************
4  * Copyright (C) 2007 by Dominic Rath *
5  * Dominic.Rath@gmx.de *
6  * *
7  * Copyright (C) 2007,2008 Øyvind Harboe *
8  * oyvind.harboe@zylin.com *
9  * *
10  * Copyright (C) 2008 by Spencer Oliver *
11  * spen@spen-soft.co.uk *
12  ***************************************************************************/
13 
14 #ifdef HAVE_CONFIG_H
15 #include "config.h"
16 #endif
17 
18 #include "log.h"
19 #include "configuration.h"
20 #include "fileio.h"
21 #include "replacements.h"
22 
23 struct fileio {
24  char *url;
25  size_t size;
26  enum fileio_type type;
27  enum fileio_access access;
28  FILE *file;
29 };
30 
31 static inline int fileio_close_local(struct fileio *fileio)
32 {
33  int retval = fclose(fileio->file);
34  if (retval != 0) {
35  if (retval == EBADF)
36  LOG_ERROR("BUG: fileio->file not a valid file descriptor");
37  else
38  LOG_ERROR("couldn't close %s: %s", fileio->url, strerror(errno));
39 
41  }
42 
43  return ERROR_OK;
44 }
45 
46 static inline int fileio_open_local(struct fileio *fileio)
47 {
48  char file_access[4];
49  ssize_t file_size;
50 
51  switch (fileio->access) {
52  case FILEIO_READ:
53  strcpy(file_access, "r");
54  break;
55  case FILEIO_WRITE:
56  strcpy(file_access, "w");
57  break;
58  case FILEIO_READWRITE:
59  strcpy(file_access, "w+");
60  break;
61  case FILEIO_APPEND:
62  strcpy(file_access, "a");
63  break;
64  case FILEIO_APPENDREAD:
65  strcpy(file_access, "a+");
66  break;
67  default:
68  LOG_ERROR("BUG: access neither read, write nor readwrite");
70  }
71 
72  /* win32 always opens in binary mode */
73 #ifndef _WIN32
74  if (fileio->type == FILEIO_BINARY)
75 #endif
76  strcat(file_access, "b");
77 
78  fileio->file = open_file_from_path(fileio->url, file_access);
79  if (!fileio->file) {
80  LOG_ERROR("couldn't open %s", fileio->url);
82  }
83 
84  file_size = 0;
85 
87  /* NB! Here we use fseek() instead of stat(), since stat is a
88  * more advanced operation that might not apply to e.g. a disk path
89  * that refers to e.g. a tftp client */
90  int result, result2;
91 
92  result = fseek(fileio->file, 0, SEEK_END);
93 
94  file_size = ftell(fileio->file);
95 
96  result2 = fseek(fileio->file, 0, SEEK_SET);
97 
98  if ((file_size < 0) || (result < 0) || (result2 < 0)) {
101  }
102  }
103 
104  fileio->size = file_size;
105 
106  return ERROR_OK;
107 }
108 
109 int fileio_open(struct fileio **fileio, const char *url,
110  enum fileio_access access_type, enum fileio_type type)
111 {
112  int retval;
113  struct fileio *tmp;
114 
115  tmp = malloc(sizeof(struct fileio));
116 
117  tmp->type = type;
118  tmp->access = access_type;
119  tmp->url = strdup(url);
120 
121  retval = fileio_open_local(tmp);
122 
123  if (retval != ERROR_OK) {
124  free(tmp->url);
125  free(tmp);
126  return retval;
127  }
128 
129  *fileio = tmp;
130 
131  return ERROR_OK;
132 }
133 
135 {
136  int retval;
137 
138  retval = fileio_close_local(fileio);
139 
140  free(fileio->url);
141  free(fileio);
142 
143  return retval;
144 }
145 
147 {
148  return feof(fileio->file);
149 }
150 
151 int fileio_seek(struct fileio *fileio, size_t position)
152 {
153  int retval;
154 
155  retval = fseek(fileio->file, position, SEEK_SET);
156 
157  if (retval != 0) {
158  LOG_ERROR("couldn't seek file %s: %s", fileio->url, strerror(errno));
160  }
161 
162  return ERROR_OK;
163 }
164 
165 static int fileio_local_read(struct fileio *fileio, size_t size, void *buffer,
166  size_t *size_read)
167 {
168  ssize_t retval;
169 
170  retval = fread(buffer, 1, size, fileio->file);
171  *size_read = (retval >= 0) ? retval : 0;
172 
173  return (retval < 0) ? retval : ERROR_OK;
174 }
175 
176 int fileio_read(struct fileio *fileio, size_t size, void *buffer,
177  size_t *size_read)
178 {
179  return fileio_local_read(fileio, size, buffer, size_read);
180 }
181 
182 int fileio_read_u32(struct fileio *fileio, uint32_t *data)
183 {
184  int retval;
185  uint8_t buf[4];
186  size_t size_read;
187 
188  retval = fileio_local_read(fileio, sizeof(uint32_t), buf, &size_read);
189 
190  if (retval == ERROR_OK && sizeof(uint32_t) != size_read)
191  retval = -EIO;
192  if (retval == ERROR_OK)
193  *data = be_to_h_u32(buf);
194 
195  return retval;
196 }
197 
198 static int fileio_local_fgets(struct fileio *fileio, size_t size, void *buffer)
199 {
200  if (!fgets(buffer, size, fileio->file))
202 
203  return ERROR_OK;
204 }
205 
206 int fileio_fgets(struct fileio *fileio, size_t size, void *buffer)
207 {
209 }
210 
211 static int fileio_local_write(struct fileio *fileio, size_t size,
212  const void *buffer, size_t *size_written)
213 {
214  ssize_t retval;
215 
216  retval = fwrite(buffer, 1, size, fileio->file);
217  *size_written = (retval >= 0) ? retval : 0;
218 
219  return (retval < 0) ? retval : ERROR_OK;
220 }
221 
222 int fileio_write(struct fileio *fileio, size_t size, const void *buffer,
223  size_t *size_written)
224 {
225  int retval;
226 
227  retval = fileio_local_write(fileio, size, buffer, size_written);
228 
229  if (retval == ERROR_OK)
230  fileio->size += *size_written;
231 
232  return retval;
233 }
234 
235 int fileio_write_u32(struct fileio *fileio, uint32_t data)
236 {
237  int retval;
238  uint8_t buf[4];
239  h_u32_to_be(buf, data);
240  size_t size_written;
241 
242  retval = fileio_write(fileio, 4, buf, &size_written);
243 
244  if (retval == ERROR_OK && size_written != sizeof(uint32_t))
245  retval = -EIO;
246 
247  return retval;
248 }
249 
259 int fileio_size(struct fileio *fileio, size_t *size)
260 {
261  *size = fileio->size;
262 
263  return ERROR_OK;
264 }
#define ERROR_COMMAND_SYNTAX_ERROR
Definition: command.h:402
FILE * open_file_from_path(const char *file, const char *mode)
Definition: configuration.c:97
uint8_t type
Definition: esp_usb_jtag.c:0
static int fileio_local_read(struct fileio *fileio, size_t size, void *buffer, size_t *size_read)
int fileio_write(struct fileio *fileio, size_t size, const void *buffer, size_t *size_written)
int fileio_seek(struct fileio *fileio, size_t position)
int fileio_write_u32(struct fileio *fileio, uint32_t data)
static int fileio_open_local(struct fileio *fileio)
Definition: helper/fileio.c:46
int fileio_read(struct fileio *fileio, size_t size, void *buffer, size_t *size_read)
int fileio_read_u32(struct fileio *fileio, uint32_t *data)
int fileio_close(struct fileio *fileio)
int fileio_size(struct fileio *fileio, size_t *size)
FIX!!!!
int fileio_fgets(struct fileio *fileio, size_t size, void *buffer)
int fileio_feof(struct fileio *fileio)
static int fileio_close_local(struct fileio *fileio)
Definition: helper/fileio.c:31
int fileio_open(struct fileio **fileio, const char *url, enum fileio_access access_type, enum fileio_type type)
static int fileio_local_fgets(struct fileio *fileio, size_t size, void *buffer)
static int fileio_local_write(struct fileio *fileio, size_t size, const void *buffer, size_t *size_written)
fileio_access
Definition: helper/fileio.h:26
@ FILEIO_WRITE
Definition: helper/fileio.h:29
@ FILEIO_READ
Definition: helper/fileio.h:28
@ FILEIO_APPENDREAD
Definition: helper/fileio.h:32
@ FILEIO_READWRITE
Definition: helper/fileio.h:30
@ FILEIO_APPEND
Definition: helper/fileio.h:31
fileio_type
Definition: helper/fileio.h:21
@ FILEIO_BINARY
Definition: helper/fileio.h:23
#define ERROR_FILEIO_OPERATION_FAILED
Definition: helper/fileio.h:56
#define LOG_ERROR(expr ...)
Definition: log.h:132
#define ERROR_OK
Definition: log.h:164
size_t size
Size of the control block search area.
Definition: rtt/rtt.c:30
FILE * file
Definition: helper/fileio.c:28
size_t size
Definition: helper/fileio.c:25
enum fileio_type type
Definition: helper/fileio.c:26
char * url
Definition: helper/fileio.c:24
enum fileio_access access
Definition: helper/fileio.c:27
static void h_u32_to_be(uint8_t *buf, uint32_t val)
Definition: types.h:186
static uint32_t be_to_h_u32(const uint8_t *buf)
Definition: types.h:139