• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

HDFGroup / hermes / 4837065844

pending completion
4837065844

Pull #515

github

GitHub
Merge 6e5aadd62 into 87672e106
Pull Request #515: v1.0

5502 of 5502 new or added lines in 117 files covered. (100.0%)

4997 of 7300 relevant lines covered (68.45%)

6198698.24 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

92.58
/adapter/stdio/stdio_api.cc
1
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2
 * Distributed under BSD 3-Clause license.                                   *
3
 * Copyright by The HDF Group.                                               *
4
 * Copyright by the Illinois Institute of Technology.                        *
5
 * All rights reserved.                                                      *
6
 *                                                                           *
7
 * This file is part of Hermes. The full Hermes copyright notice, including  *
8
 * terms governing use, modification, and redistribution, is contained in    *
9
 * the COPYING file, which can be found at the top directory. If you do not  *
10
 * have access to the file, you may request a copy from help@hdfgroup.org.   *
11
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
12

13
bool stdio_intercepted = true;
14

15
#include <limits.h>
16
#include <sys/file.h>
17
#include <cstdio>
18
#include "stdio_api.h"
19
#include "stdio_fs_api.h"
20
#include "interceptor.h"
21

22
using hermes::adapter::fs::MetadataManager;
23
using hermes::adapter::fs::SeekMode;
24
using hermes::adapter::fs::AdapterStat;
25
using hermes::adapter::fs::File;
26

27
namespace hapi = hermes::api;
28
namespace stdfs = std::filesystem;
29
using hermes::u8;
30
using hermes::u64;
31

32
extern "C" {
33

34
/**
35
 * STDIO
36
 */
37

38
FILE *HERMES_DECL(fopen)(const char *path, const char *mode) {
1,906✔
39
  TRANSPARENT_HERMES
1,906✔
40
  auto real_api = HERMES_STDIO_API;
1,906✔
41
  auto fs_api = HERMES_STDIO_FS;
1,906✔
42
  if (fs_api->IsPathTracked(path)) {
3,779✔
43
    HILOG(kDebug, "Intercepting fopen({}, {})", path, mode)
402✔
44
    AdapterStat stat;
402✔
45
    stat.mode_str_ = mode;
402✔
46
    return fs_api->Open(stat, path).hermes_fh_;
804✔
47
  } else {
48
    return real_api->fopen(path, mode);
1,504✔
49
  }
50
}
51

52
FILE *HERMES_DECL(fopen64)(const char *path, const char *mode) {
46✔
53
  TRANSPARENT_HERMES
46✔
54
  auto real_api = HERMES_STDIO_API;
46✔
55
  auto fs_api = HERMES_STDIO_FS;
46✔
56
  if (fs_api->IsPathTracked(path)) {
92✔
57
    HILOG(kDebug, "Intercepting fopen64({}, {})", path, mode)
24✔
58
    AdapterStat stat;
24✔
59
    stat.mode_str_ = mode;
24✔
60
    return fs_api->Open(stat, path).hermes_fh_;
48✔
61
  } else {
62
    return real_api->fopen64(path, mode);
22✔
63
  }
64
}
65

66
FILE *HERMES_DECL(fdopen)(int fd, const char *mode) {
84✔
67
  TRANSPARENT_HERMES
95✔
68
  auto real_api = HERMES_STDIO_API;
84✔
69
  auto fs_api = HERMES_STDIO_FS;
84✔
70
  std::shared_ptr<AdapterStat> stat;
84✔
71
  if (fs_api->IsFdTracked(fd, stat)) {
84✔
72
    HILOG(kDebug, "Intercepting fdopen({})", fd, mode)
×
73
    return fs_api->FdOpen(mode, stat);
×
74
  } else {
75
    return real_api->fdopen(fd, mode);
84✔
76
  }
77
}
78

79
FILE *HERMES_DECL(freopen)(const char *path, const char *mode, FILE *stream) {
12✔
80
  TRANSPARENT_HERMES
12✔
81
  auto real_api = HERMES_STDIO_API;
12✔
82
  auto fs_api = HERMES_STDIO_FS;
12✔
83
  if (fs_api->IsFpTracked(stream)) {
12✔
84
    HILOG(kDebug, "Intercepting freopen({}, {})", path, mode)
12✔
85
    return fs_api->Reopen(path, mode, *(AdapterStat*)stream);
24✔
86
  }
87
  return real_api->freopen(path, mode, stream);
×
88
}
89

90
FILE *HERMES_DECL(freopen64)(const char *path, const char *mode, FILE *stream) {
12✔
91
  TRANSPARENT_HERMES
12✔
92
  auto real_api = HERMES_STDIO_API;
12✔
93
  auto fs_api = HERMES_STDIO_FS;
12✔
94
  if (fs_api->IsFpTracked(stream)) {
12✔
95
    HILOG(kDebug, "Intercepting freopen64({}, {})", path, mode)
12✔
96
    return fs_api->Reopen(path, mode, *(AdapterStat*)stream);
24✔
97
  }
98
  return real_api->freopen64(path, mode, stream);
×
99
}
100

101
int HERMES_DECL(fflush)(FILE *fp) {
322,464✔
102
  bool stat_exists;
322,464✔
103
  auto real_api = HERMES_STDIO_API;
322,464✔
104
  auto fs_api = HERMES_STDIO_FS;
322,464✔
105
  if (fs_api->IsFpTracked(fp)) {
322,464✔
106
    HILOG(kDebug, "Intercepting fflush")
210✔
107
    File f;
420✔
108
    f.hermes_fh_ = fp;
210✔
109
    return fs_api->Sync(f, stat_exists);
210✔
110
  }
111
  return real_api->fflush(fp);
322,254✔
112
}
113

114
int HERMES_DECL(fclose)(FILE *fp) {
1,985✔
115
  bool stat_exists;
1,985✔
116
  auto real_api = HERMES_STDIO_API;
1,985✔
117
  auto fs_api = HERMES_STDIO_FS;
1,985✔
118
  if (fs_api->IsFpTracked(fp)) {
1,985✔
119
    HILOG(kDebug, "Intercepting fclose({})", (void*)fp)
411✔
120
    File f; f.hermes_fh_ = fp;
822✔
121
    return fs_api->Close(f, stat_exists);
411✔
122
  }
123
  return real_api->fclose(fp);
1,574✔
124
}
125

126
size_t HERMES_DECL(fwrite)(const void *ptr, size_t size, size_t nmemb,
341,902✔
127
                           FILE *fp) {
128
  bool stat_exists;
341,902✔
129
  auto real_api = HERMES_STDIO_API;
341,902✔
130
  auto fs_api = HERMES_STDIO_FS;
341,902✔
131
  if (fs_api->IsFpTracked(fp)) {
341,902✔
132
    HILOG(kDebug, "Intercepting fwrite with size: {} and nmemb: {}",
8,469✔
133
          size, nmemb)
134
    File f; f.hermes_fh_ = fp;
16,938✔
135
    IoStatus io_status;
8,469✔
136
    int ret = fs_api->Write(f, stat_exists, ptr, size * nmemb, io_status);
8,469✔
137
    if (ret > 0) {
8,469✔
138
      return ret / size;
8,469✔
139
    } else {
140
      return ret;
×
141
    }
142
  }
143
  return real_api->fwrite(ptr, size, nmemb, fp);
333,433✔
144
}
145

146
int HERMES_DECL(fputc)(int c, FILE *fp) {
192✔
147
  bool stat_exists;
192✔
148
  auto real_api = HERMES_STDIO_API;
192✔
149
  auto fs_api = HERMES_STDIO_FS;
192✔
150
  if (fs_api->IsFpTracked(fp)) {
192✔
151
    HILOG(kDebug, "Intercepting fputc({})", c)
192✔
152
    File f; f.hermes_fh_ = fp;
192✔
153
    IoStatus io_status;
192✔
154
    fs_api->Write(f, stat_exists, &c, 1, io_status);
192✔
155
    if (stat_exists) {
192✔
156
      return c;
192✔
157
    }
158
  }
159
  return real_api->fputc(c, fp);
×
160
}
161

162
int HERMES_DECL(fgetpos)(FILE *fp, fpos_t *pos) {
9✔
163
  bool stat_exists;
9✔
164
  auto real_api = HERMES_STDIO_API;
9✔
165
  auto fs_api = HERMES_STDIO_FS;
9✔
166
  if (fs_api->IsFpTracked(fp) && pos) {
9✔
167
    File f; f.hermes_fh_ = fp;
9✔
168
    HILOG(kDebug, "Intercepting fgetpos")
9✔
169
    // TODO(chogan): @portability In the GNU C Library, fpos_t is an opaque
170
    // data structure that contains internal data to represent file offset and
171
    // conversion state information. In other systems, it might have a
172
    // different internal representation. This will need to change to support
173
    // other compilers.
174
    pos->__pos = fs_api->Tell(f, stat_exists);
9✔
175
    if (stat_exists) {
9✔
176
      return 0;
9✔
177
    }
178
  }
179
  return real_api->fgetpos(fp, pos);
×
180
}
181

182
int HERMES_DECL(fgetpos64)(FILE *fp, fpos64_t *pos) {
9✔
183
  bool stat_exists;
9✔
184
  auto real_api = HERMES_STDIO_API;
9✔
185
  auto fs_api = HERMES_STDIO_FS;
9✔
186
  if (fs_api->IsFpTracked(fp) && pos) {
9✔
187
    File f; f.hermes_fh_ = fp;
18✔
188
    HILOG(kDebug, "Intercepting fgetpos64")
9✔
189
    // TODO(chogan): @portability In the GNU C Library, fpos_t is an opaque
190
    // data structure that contains internal data to represent file offset and
191
    // conversion state information. In other systems, it might have a
192
    // different internal representation. This will need to change to support
193
    // other compilers.
194
    pos->__pos = fs_api->Tell(f, stat_exists);
9✔
195
    return 0;
9✔
196
  }
197
  return real_api->fgetpos64(fp, pos);
×
198
}
199

200
int HERMES_DECL(putc)(int c, FILE *fp) {
192✔
201
  bool stat_exists;
192✔
202
  auto real_api = HERMES_STDIO_API;
192✔
203
  auto fs_api = HERMES_STDIO_FS;
192✔
204
  if (fs_api->IsFpTracked(fp)) {
192✔
205
    File f; f.hermes_fh_ = fp;
384✔
206
    IoStatus io_status;
192✔
207
    HILOG(kDebug, "Intercepting putc")
192✔
208
    fs_api->Write(f, stat_exists, &c, 1, io_status);
192✔
209
    return c;
192✔
210
  }
211
  return real_api->fputc(c, fp);
×
212
}
213

214
int HERMES_DECL(putw)(int w, FILE *fp) {
192✔
215
  bool stat_exists;
192✔
216
  auto real_api = HERMES_STDIO_API;
192✔
217
  auto fs_api = HERMES_STDIO_FS;
192✔
218
  if (fs_api->IsFpTracked(fp)) {
192✔
219
    HILOG(kDebug, "Intercepting putw")
192✔
220
    File f; f.hermes_fh_ = fp;
384✔
221
    IoStatus io_status;
192✔
222
    int ret = fs_api->Write(f, stat_exists, &w, sizeof(w), io_status);
192✔
223
    if (ret == sizeof(w)) {
192✔
224
      return 0;
225
    } else {
226
      return EOF;
×
227
    }
228
  }
229
  return real_api->putw(w, fp);
×
230
}
231

232
int HERMES_DECL(fputs)(const char *s, FILE *stream) {
3✔
233
  bool stat_exists;
3✔
234
  auto real_api = HERMES_STDIO_API;
3✔
235
  auto fs_api = HERMES_STDIO_FS;
3✔
236
  if (fs_api->IsFpTracked(stream)) {
3✔
237
    HILOG(kDebug, "Intercepting fputs")
3✔
238
    File f; f.hermes_fh_ = stream;
6✔
239
    IoStatus io_status;
3✔
240
    return fs_api->Write(f, stat_exists, s, strlen(s), io_status);
3✔
241
  }
242
  return real_api->fputs(s, stream);
×
243
}
244

245
size_t HERMES_DECL(fread)(void *ptr, size_t size, size_t nmemb, FILE *stream) {
18,355✔
246
  bool stat_exists;
18,355✔
247
  auto real_api = HERMES_STDIO_API;
18,355✔
248
  auto fs_api = HERMES_STDIO_FS;
18,355✔
249
  if (fs_api->IsFpTracked(stream)) {
18,355✔
250
    HILOG(kDebug, "Intercepting fread with size: {} and nmemb: {}",
8,559✔
251
          size, nmemb)
252
    File f; f.hermes_fh_ = stream;
17,118✔
253
    IoStatus io_status;
8,559✔
254
    int ret = fs_api->Read(f, stat_exists, ptr, size * nmemb, io_status);
8,559✔
255
    if (ret > 0) {
8,559✔
256
      return ret / size;
8,305✔
257
    } else {
258
      return ret;
254✔
259
    }
260
  }
261
  return real_api->fread(ptr, size, nmemb, stream);
9,796✔
262
}
263

264
int HERMES_DECL(fgetc)(FILE *stream) {
192✔
265
  bool stat_exists;
192✔
266
  auto real_api = HERMES_STDIO_API;
192✔
267
  auto fs_api = HERMES_STDIO_FS;
192✔
268
  if (fs_api->IsFpTracked(stream)) {
192✔
269
    HILOG(kDebug, "Intercepting fgetc")
192✔
270
    File f; f.hermes_fh_ = stream;
384✔
271
    IoStatus io_status;
192✔
272
    u8 value;
192✔
273
    fs_api->Read(f, stat_exists, &value, sizeof(u8), io_status);
192✔
274
    return value;
192✔
275
  }
276
  return real_api->fgetc(stream);
×
277
}
278

279
int HERMES_DECL(getc)(FILE *stream) {
214✔
280
  bool stat_exists;
214✔
281
  auto real_api = HERMES_STDIO_API;
214✔
282
  auto fs_api = HERMES_STDIO_FS;
214✔
283
  if (fs_api->IsFpTracked(stream)) {
214✔
284
    HILOG(kDebug, "Intercepting getc")
192✔
285
    File f; f.hermes_fh_ = stream;
384✔
286
    IoStatus io_status;
192✔
287
    u8 value;
192✔
288
    fs_api->Read(f, stat_exists, &value, sizeof(u8), io_status);
192✔
289
    return value;
192✔
290
  }
291
  return real_api->getc(stream);
22✔
292
}
293

294
int HERMES_DECL(getw)(FILE *stream) {
192✔
295
  bool stat_exists;
192✔
296
  auto real_api = HERMES_STDIO_API;
192✔
297
  auto fs_api = HERMES_STDIO_FS;
192✔
298
  if (fs_api->IsFpTracked(stream)) {
192✔
299
    HILOG(kDebug, "Intercepting getw")
192✔
300
    File f; f.hermes_fh_ = stream;
384✔
301
    IoStatus io_status;
192✔
302
    int value;
192✔
303
    fs_api->Read(f, stat_exists, &value, sizeof(int), io_status);
192✔
304
    return value;
192✔
305
  }
306
  return real_api->getc(stream);
×
307
}
308

309
char *HERMES_DECL(fgets)(char *s, int size, FILE *stream) {
1,609✔
310
  bool stat_exists;
1,609✔
311
  auto real_api = HERMES_STDIO_API;
1,609✔
312
  auto fs_api = HERMES_STDIO_FS;
1,609✔
313
  if (fs_api->IsFpTracked(stream)) {
1,609✔
314
    HILOG(kDebug, "Intercepting fgets")
3✔
315
    File f; f.hermes_fh_ = stream;
6✔
316
    IoStatus io_status;
3✔
317
    size_t read_size = size - 1;
3✔
318
    size_t ret_size = fs_api->Read(f, stat_exists, s, read_size, io_status);
3✔
319
    if (ret_size < read_size) {
3✔
320
      /* FILE ended */
321
      read_size = ret_size;
322
    }
323
    /* Check if \0 or \n in s.*/
324
    size_t copy_pos = 0;
3✔
325
    for (size_t i = 0; i < read_size; ++i) {
196,608✔
326
      if (s[i] == '\0' || s[i] == '\n') {
196,605✔
327
        copy_pos = i;
328
        break;
329
      }
330
    }
331
    if (copy_pos > 0) {
3✔
332
      /* \n and \0 was found. */
333
      s[copy_pos + 1] = '\0';
×
334
    } else {
335
      s[read_size] = '\0';
3✔
336
    }
337
    return s;
3✔
338
  }
339
  return real_api->fgets(s, size, stream);
1,606✔
340
}
341

342
void HERMES_DECL(rewind)(FILE *stream) {
6✔
343
  bool stat_exists;
6✔
344
  auto real_api = HERMES_STDIO_API;
6✔
345
  auto fs_api = HERMES_STDIO_FS;
6✔
346
  if (fs_api->IsFpTracked(stream)) {
6✔
347
    HILOG(kDebug, "Intercepting rewind")
6✔
348
    File f; f.hermes_fh_ = stream;
12✔
349
    fs_api->Seek(f, stat_exists, SeekMode::kSet, 0);
6✔
350
    return;
6✔
351
  }
352
  real_api->rewind(stream);
×
353
}
354

355
int HERMES_DECL(fseek)(FILE *stream, long offset, int whence) {
25,417✔
356
  bool stat_exists;
25,417✔
357
  auto real_api = HERMES_STDIO_API;
25,417✔
358
  auto fs_api = HERMES_STDIO_FS;
25,417✔
359
  if (fs_api->IsFpTracked(stream)) {
25,417✔
360
    HILOG(kDebug, "Intercepting fseek offset: {} whence: {}",
12,714✔
361
          offset, whence)
362
    File f; f.hermes_fh_ = stream;
25,428✔
363
    fs_api->Seek(f, stat_exists, static_cast<SeekMode>(whence), offset);
12,714✔
364
    return 0;
12,714✔
365
  }
366
  return real_api->fseek(stream, offset, whence);
12,703✔
367
}
368

369
int HERMES_DECL(fseeko)(FILE *stream, off_t offset, int whence) {
18✔
370
  bool stat_exists;
18✔
371
  auto real_api = HERMES_STDIO_API;
18✔
372
  auto fs_api = HERMES_STDIO_FS;
18✔
373
  if (fs_api->IsFpTracked(stream)) {
18✔
374
    HILOG(kDebug, "Intercepting fseeko offset: {} whence: {}",
18✔
375
          offset, whence)
376
    File f; f.hermes_fh_ = stream;
36✔
377
    fs_api->Seek(f, stat_exists, static_cast<SeekMode>(whence), offset);
18✔
378
    return 0;
18✔
379
  }
380
  return real_api->fseeko(stream, offset, whence);
×
381
}
382

383
int HERMES_DECL(fseeko64)(FILE *stream, off64_t offset, int whence) {
12✔
384
  bool stat_exists;
12✔
385
  auto real_api = HERMES_STDIO_API;
12✔
386
  auto fs_api = HERMES_STDIO_FS;
12✔
387
  if (fs_api->IsFpTracked(stream)) {
12✔
388
    HILOG(kDebug, "Intercepting fseeko64 offset: {} whence: {}",
12✔
389
          offset, whence)
390
    File f; f.hermes_fh_ = stream;
24✔
391
    fs_api->Seek(f, stat_exists, static_cast<SeekMode>(whence), offset);
12✔
392
    return 0;
12✔
393
  }
394
  return real_api->fseeko64(stream, offset, whence);
×
395
}
396

397
int HERMES_DECL(fsetpos)(FILE *stream, const fpos_t *pos) {
6✔
398
  bool stat_exists;
6✔
399
  auto real_api = HERMES_STDIO_API;
6✔
400
  auto fs_api = HERMES_STDIO_FS;
6✔
401
  off_t offset = pos->__pos;
6✔
402
  if (fs_api->IsFpTracked(stream)) {
6✔
403
    HILOG(kDebug, "Intercepting fsetpos offset: {}",
6✔
404
          offset)
405
    File f; f.hermes_fh_ = stream;
12✔
406
    fs_api->Seek(f, stat_exists, SeekMode::kSet, offset);
6✔
407
    return 0;
6✔
408
  }
409
  return real_api->fsetpos(stream, pos);
×
410
}
411

412
int HERMES_DECL(fsetpos64)(FILE *stream, const fpos64_t *pos) {
6✔
413
  bool stat_exists;
6✔
414
  auto real_api = HERMES_STDIO_API;
6✔
415
  auto fs_api = HERMES_STDIO_FS;
6✔
416
  off_t offset = pos->__pos;
6✔
417
  if (fs_api->IsFpTracked(stream)) {
6✔
418
    HILOG(kDebug, "Intercepting fsetpos64 offset: {}",
6✔
419
          offset)
420
    File f; f.hermes_fh_ = stream;
12✔
421
    fs_api->Seek(f, stat_exists, SeekMode::kSet, offset);
6✔
422
    return 0;
6✔
423
  }
424
  return real_api->fsetpos64(stream, pos);
×
425
}
426

427
long int HERMES_DECL(ftell)(FILE *fp) {
2,766✔
428
  bool stat_exists;
2,766✔
429
  auto real_api = HERMES_STDIO_API;
2,766✔
430
  auto fs_api = HERMES_STDIO_FS;
2,766✔
431
  if (fs_api->IsFpTracked(fp)) {
2,766✔
432
    HILOG(kDebug, "Intercepting ftell")
2,766✔
433
    File f; f.hermes_fh_ = fp;
5,532✔
434
    off_t ret = fs_api->Tell(f, stat_exists);
2,766✔
435
    return ret;
2,766✔
436
  }
437
  return real_api->ftell(fp);
×
438
}
439

440
}  // extern C
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc