jtag: linuxgpiod: drop extra parenthesis
[openocd.git] / src / helper / fileio.c
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
40 return ERROR_FILEIO_OPERATION_FAILED;
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");
69 return ERROR_COMMAND_SYNTAX_ERROR;
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);
81 return ERROR_FILEIO_OPERATION_FAILED;
82 }
83
84 file_size = 0;
85
86 if ((fileio->access != FILEIO_WRITE) || (fileio->access == FILEIO_READWRITE)) {
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)) {
99 fileio_close_local(fileio);
100 return ERROR_FILEIO_OPERATION_FAILED;
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
134 int fileio_close(struct fileio *fileio)
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
146 int fileio_feof(struct fileio *fileio)
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));
159 return ERROR_FILEIO_OPERATION_FAILED;
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))
201 return ERROR_FILEIO_OPERATION_FAILED;
202
203 return ERROR_OK;
204 }
205
206 int fileio_fgets(struct fileio *fileio, size_t size, void *buffer)
207 {
208 return fileio_local_fgets(fileio, size, buffer);
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
250 /**
251 * FIX!!!!
252 *
253 * For now this can not fail, but that's because a seek was executed
254 * on startup.
255 *
256 * Avoiding the seek on startup opens up for using streams.
257 *
258 */
259 int fileio_size(struct fileio *fileio, size_t *size)
260 {
261 *size = fileio->size;
262
263 return ERROR_OK;
264 }

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)