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

proftpd / proftpd / 26127302554

19 May 2026 07:34PM UTC coverage: 92.635% (-0.4%) from 93.024%
26127302554

push

github

Castaglia
Make a flaky, racy mod_copy regression test more reliable.

47303 of 51064 relevant lines covered (92.63%)

241.07 hits per line

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

99.12
/src/error.c
1
/*
2
 * ProFTPD - FTP server daemon
3
 * Copyright (c) 2016-2026 The ProFTPD Project team
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, see <https://www.gnu.org/licenses/>.
17
 *
18
 * As a special exemption, The ProFTPD Project team and other respective
19
 * copyright holders give permission to link this program with OpenSSL, and
20
 * distribute the resulting executable, without including the source code for
21
 * OpenSSL in the source distribution.
22
 */
23

24
/* Error API */
25

26
#include "error.h"
27
#include "proftpd.h"
28
#include "str.h"
29
#include "support.h"
30
#include "session.h"
31
#include "trace.h"
32

33
#define PR_ERROR_BUFSZ                32
34

35
struct err_rec {
36
  pool *err_pool;
37

38
  /* Actual errno value, or -1 if unknown */
39
  int err_errno;
40

41
  /* String of errno name, e.g. "EINVAL" */
42
  const char *err_name;
43

44
  /* strerror(3) value, or NULL if unknown. */
45
  const char *err_desc;
46

47
  /* Module where the error occurred, if known. */
48
  module *err_module;
49

50
  /* File location of the error, e.g. __FILE__. */
51
  const char *err_file;
52

53
  /* Line number in file of the error, e.g. __LINE__. */
54
  unsigned int err_lineno;
55

56
  /* Process identity at time of error. */
57
  const char *err_user;
58
  uid_t err_uid;
59
  gid_t err_gid;
60

61
  /* Components for use in a more detailed error message:
62
   *
63
   * goal (the why)
64
   * operation (the what)
65
   */
66
  const char *err_goal;
67
  const char *err_oper;
68
  const char *err_args;
69
  const char *err_explained;
70
};
71

72
static unsigned int error_details = PR_ERROR_DETAILS_DEFAULT;
73
static unsigned int error_formats = PR_ERROR_FORMAT_DEFAULT;
74

75
struct err_explainer {
76
  struct err_explainer *next, *prev;
77

78
  module *m;
79
  const char *name;
80
  pr_error_explainer_t *explainer;
81
};
82

83
/* List of registered explainers. */
84
static struct err_explainer *error_explainers = NULL;
85

86
/* Currently selected explainers. */
87
static struct err_explainer *error_explainer = NULL;
88

89
struct errno_info {
90
  int error_number;
91
  const char *name;
92
};
93

94
static struct errno_info errno_names[] = {
95
#ifdef E2BIG
96
  { E2BIG, "E2BIG" },
97
#endif /* E2BIG */
98
#ifdef EACCES
99
  { EACCES, "EACCES" },
100
#endif /* EACCES */
101
#ifdef EADDRINUSE
102
  { EADDRINUSE, "EADDRINUSE" },
103
#endif /* EADDRINUSE */
104
#ifdef EADDRNOTAVAIL
105
  { EADDRNOTAVAIL, "EADDRNOTAVAIL" },
106
#endif /* EADDRNOTAVAIL */
107
#ifdef EAFNOSUPPORT
108
  { EAFNOSUPPORT, "EAFNOSUPPORT" },
109
#endif /* EAFNOSUPPORT */
110
#ifdef EAGAIN
111
  { EAGAIN, "EAGAIN" },
112
#endif /* EAGAIN */
113
#ifdef EALREADY
114
  { EALREADY, "EALREADY" },
115
#endif /* EALREADY */
116
#ifdef EBADF
117
  { EBADF, "EBADF" },
118
#endif /* EBADF */
119
#ifdef EBADFD
120
  { EBADFD, "EBADFD" },
121
#endif /* EBADFD */
122
#ifdef EBUSY
123
  { EBUSY, "EBUSY" },
124
#endif /* EBUSY */
125
#ifdef ECANCELED
126
  { ECANCELED, "ECANCELED" },
127
#endif /* ECANCELED */
128
#ifdef ECOMM
129
  { ECOMM, "ECOMM" },
130
#endif /* ECOMM */
131
#ifdef ECONNABORTED
132
  { ECONNABORTED, "ECONNABORTED" },
133
#endif /* ECONNABORTED */
134
#ifdef ECONNREFUSED
135
  { ECONNREFUSED, "ECONNREFUSED" },
136
#endif /* ECONNREFUSED */
137
#ifdef ECONNRESET
138
  { ECONNRESET, "ECONNRESET" },
139
#endif /* ECONNRESET */
140
#ifdef EDEADLK
141
  { EDEADLK, "EDEADLK" },
142
#endif /* EDEADLK */
143
#ifdef EDEADLOCK
144
  { EDEADLOCK, "EDEADLOCK" },
145
#endif /* EDEADLOCK */
146
#ifdef EDQUOT
147
  { EDQUOT, "EDQUOT" },
148
#endif /* EDQUOT */
149
#ifdef EEXIST
150
  { EEXIST, "EEXIST" },
151
#endif /* EEXIST */
152
#ifdef EFAULT
153
  { EFAULT, "EFAULT" },
154
#endif /* EFAULT */
155
#ifdef EFBIG
156
  { EFBIG, "EFBIG" },
157
#endif /* EFBIG */
158
#ifdef EHOSTDOWN
159
  { EHOSTDOWN, "EHOSTDOWN" },
160
#endif /* EHOSTDOWN */
161
#ifdef EHOSTUNREACH
162
  { EHOSTUNREACH, "EHOSTUNREACH" },
163
#endif /* EHOSTUNREACH */
164
#ifdef EILSEQ
165
  { EILSEQ, "EILSEQ" },
166
#endif /* EILSEQ */
167
#ifdef EINPROGRESS
168
  { EINPROGRESS, "EINPROGRESS" },
169
#endif /* EINPROGRESS */
170
#ifdef EINTR
171
  { EINTR, "EINTR" },
172
#endif /* EINTR */
173
#ifdef EINVAL
174
  { EINVAL, "EINVAL" },
175
#endif /* EINVAL */
176
#ifdef EISCONN
177
  { EISCONN, "EISCONN" },
178
#endif /* EISCONN */
179
#ifdef EISDIR
180
  { EISDIR, "EISDIR" },
181
#endif /* EISDIR */
182
#ifdef EIO
183
  { EIO, "EIO" },
184
#endif /* EIO */
185
#ifdef ELOOP
186
  { ELOOP, "ELOOP" },
187
#endif /* ELOOP */
188
#ifdef EMFILE
189
  { EMFILE, "EMFILE" },
190
#endif /* EMFILE */
191
#ifdef EMLINK
192
  { EMLINK, "EMLINK" },
193
#endif /* EMLINK */
194
#ifdef EMSGSIZE
195
  { EMSGSIZE, "EMSGSIZE" },
196
#endif /* EMSGSIZE */
197
#ifdef ENAMETOOLONG
198
  { ENAMETOOLONG, "ENAMETOOLONG" },
199
#endif /* ENAMETOOLONG */
200
#ifdef ENFILE
201
  { ENFILE, "ENFILE" },
202
#endif /* ENFILE */
203
#ifdef ENETDOWN
204
  { ENETDOWN, "ENETDOWN" },
205
#endif /* ENETDOWN */
206
#ifdef ENETRESET
207
  { ENETRESET, "ENETRESET" },
208
#endif /* ENETRESET */
209
#ifdef ENETUNREACH
210
  { ENETUNREACH, "ENETUNREACH" },
211
#endif /* ENETUNREACH */
212
#ifdef ENOBUFS
213
  { ENOBUFS, "ENOBUFS" },
214
#endif /* ENOBUFS */
215
#ifdef ENODATA
216
  { ENODATA, "ENODATA" },
217
#endif /* ENODATA */
218
#ifdef ENOATTR
219
  { ENOATTR, "ENOATTR" },
220
#endif /* ENOATTR */
221
#ifdef ENOLCK
222
  { ENOLCK, "ENOLCK" },
223
#endif /* ENOLCK */
224
#ifdef ENOLINK
225
  { ENOLINK, "ENOLINK" },
226
#endif /* ENOLINK */
227
#ifdef ENOMEDIUM
228
  { ENOMEDIUM, "ENOMEDIUM" },
229
#endif /* ENOMEDIUM */
230
#ifdef ENOMEM
231
  { ENOMEM, "ENOMEM" },
232
#endif /* ENOMEM */
233
#ifdef ENONET
234
  { ENONET, "ENONET" },
235
#endif /* ENONET */
236
#ifdef ENOTCONN
237
  { ENOTCONN, "ENOTCONN" },
238
#endif /* ENOTSCONN */
239
#ifdef ENOTEMPTY
240
  { ENOTEMPTY, "ENOTEMPTY" },
241
#endif /* ENOTEMPTY */
242
#ifdef ENOSPC
243
  { ENOSPC, "ENOSPC" },
244
#endif /* ENOSPC */
245
#ifdef ENOSYS
246
  { ENOSYS, "ENOSYS" },
247
#endif /* ENOSYS */
248
#ifdef ENXIO
249
  { ENXIO, "ENXIO" },
250
#endif /* ENXIO */
251
#ifdef ENOENT
252
  { ENOENT, "ENOENT" },
253
#endif /* ENOENT */
254
#ifdef ENOTDIR
255
  { ENOTDIR, "ENOTDIR" },
256
#endif /* ENOTDIR */
257
#ifdef ENOTSOCK
258
  { ENOTSOCK, "ENOTSOCK" },
259
#endif /* ENOTSOCK */
260
#ifdef ENOTSUP
261
  { ENOTSUP, "ENOTSUP" },
262
#endif /* ENOTSUP */
263
#ifdef EOPNOTSUPP
264
  { EOPNOTSUPP, "EOPNOTSUPP" },
265
#endif /* EOPNOTSUPP */
266
#ifdef EPERM
267
  { EPERM, "EPERM" },
268
#endif /* EPERM */
269
#ifdef EPFNOSUPPORT
270
  { EPFNOSUPPORT, "EPFNOSUPPORT" },
271
#endif /* EPFNOSUPPORT */
272
#ifdef EPIPE
273
  { EPIPE, "EPIPE" },
274
#endif /* EPIPE */
275
#ifdef EPROTO
276
  { EPROTO, "EPROTO" },
277
#endif /* EPROTO */
278
#ifdef EPROTONOSUPPORT
279
  { EPROTONOSUPPORT, "EPROTONOSUPPORT" },
280
#endif /* EPROTONOSUPPORT */
281
#ifdef EPROTOOPT
282
  { EPROTOOPT, "EPROTOOPT" },
283
#endif /* EPROTOOPT */
284
#ifdef EPROTOTYPE
285
  { EPROTOTYPE, "EPROTOTYPE" },
286
#endif /* EPROTOTYPE */
287
#ifdef ERANGE
288
  { ERANGE, "ERANGE" },
289
#endif /* ERANGE */
290
#ifdef EROFS
291
  { EROFS, "EROFS" },
292
#endif /* EROFS */
293
#ifdef ESHUTDOWN
294
  { ESHUTDOWN, "ESHUTDOWN" },
295
#endif /* ESHUTDOWN */
296
#ifdef ESPIPE
297
  { ESPIPE, "ESPIPE" },
298
#endif /* ESPIPE */
299
#ifdef ERESTART
300
  { ERESTART, "ERESTART" },
301
#endif /* ERESTART */
302
#ifdef ESRCH
303
  { ESRCH, "ESRCH" },
304
#endif /* ESRCH */
305
#ifdef ESTALE
306
  { ESTALE, "ESTALE" },
307
#endif /* ESTALE */
308
#ifdef ETIMEDOUT
309
  { ETIMEDOUT, "ETIMEDOUT" },
310
#endif /* ETIMEDOUT */
311
#ifdef ETXTBSY
312
  { ETXTBSY, "ETXTBSY" },
313
#endif /* ETXTBSY */
314
#ifdef EWOULDBLOCK
315
  { EWOULDBLOCK, "EWOULDBLOCK" },
316
#endif /* EWOULDBLOCK */
317
#ifdef EXDEV
318
  { EXDEV, "EXDEV" },
319
#endif /* EXDEV */
320

321
  { -1, NULL }
322
};
323

324
static const char *trace_channel = "error";
325

326
pr_error_t *pr_error_create(pool *p, int xerrno) {
121✔
327
  pr_error_t *err;
328
  pool *err_pool;
329

330
  /* Known errno values are not negative.  Right? */
331

332
  if (p == NULL ||
242✔
333
      xerrno < 0) {
121✔
334
    errno = EINVAL;
2✔
335
    return NULL;
2✔
336
  }
337

338
  err_pool = make_sub_pool(p);
119✔
339
  pr_pool_tag(err_pool, "error pool");
119✔
340

341
  err = pcalloc(err_pool, sizeof(pr_error_t));
119✔
342
  err->err_pool = err_pool;
119✔
343
  err->err_errno = xerrno;
119✔
344

345
  if (session.user != NULL) {
119✔
346
    err->err_user = pstrdup(err_pool, session.user);
2✔
347
  }
348

349
  /* NOTE: Should we get the real UID/GID here too? */
350
  err->err_uid = geteuid();
119✔
351
  err->err_gid = getegid();
119✔
352

353
  return err;
119✔
354
}
355

356
void pr_error_destroy(pr_error_t *err) {
120✔
357
  int xerrno;
358

359
  xerrno = errno;
120✔
360

361
  if (err != NULL) {
120✔
362
    destroy_pool(err->err_pool);
119✔
363
  }
364

365
  errno = xerrno;
120✔
366
}
120✔
367

368
int pr_error_get_who(pr_error_t *err, uid_t *err_uid, gid_t *err_gid) {
5✔
369
  if (err == NULL) {
5✔
370
    errno = EINVAL;
1✔
371
    return -1;
1✔
372
  }
373

374
  if (err_uid == NULL &&
8✔
375
      err_gid == NULL) {
4✔
376
    errno = EINVAL;
1✔
377
    return -1;
1✔
378
  }
379

380
  if (err_uid != NULL) {
3✔
381
    *err_uid = err->err_uid;
2✔
382
  }
383

384
  if (err_gid != NULL) {
3✔
385
    *err_gid = err->err_gid;
2✔
386
  }
387

388
  return 0;
389
}
390

391
int pr_error_set_why(pr_error_t *err, const char *why) {
12✔
392
  if (err == NULL ||
24✔
393
      why == NULL) {
12✔
394
    errno = EINVAL;
6✔
395
    return -1;
6✔
396
  }
397

398
  err->err_goal = pstrdup(err->err_pool, why);
6✔
399
  return 0;
6✔
400
}
401

402
int pr_error_set_where(pr_error_t *err, module *m, const char *file,
10✔
403
    unsigned int lineno) {
404

405
  if (err == NULL) {
10✔
406
    errno = EINVAL;
5✔
407
    return -1;
5✔
408
  }
409

410
  err->err_module = m;
5✔
411
  err->err_file = file;
5✔
412
  err->err_lineno = lineno;
5✔
413

414
  return 0;
5✔
415
}
416

417
int pr_error_set_what(pr_error_t *err, const char *what) {
227✔
418
  if (err == NULL ||
454✔
419
      what == NULL) {
227✔
420
    errno = EINVAL;
2✔
421
    return -1;
2✔
422
  }
423

424
  err->err_oper = pstrdup(err->err_pool, what);
225✔
425
  return 0;
225✔
426
}
427

428
unsigned int pr_error_use_details(unsigned int use_details) {
8✔
429
  unsigned int prev;
430

431
  prev = error_details;
8✔
432
  error_details = use_details;
8✔
433

434
  return prev;
8✔
435
}
436

437
unsigned int pr_error_use_formats(unsigned int use_formats) {
6✔
438
  unsigned int prev;
439

440
  prev = error_formats;
6✔
441
  error_formats = use_formats;
6✔
442

443
  return prev;
6✔
444
}
445

446
static const char *get_uid(pr_error_t *err, char *uid, size_t uidsz) {
11✔
447
  memset(uid, '\0', uidsz);
11✔
448
  pr_snprintf(uid, uidsz-1, "%lu", (unsigned long) err->err_uid);
11✔
449
  return uid;
11✔
450
}
451

452
static const char *get_gid(pr_error_t *err, char *gid, size_t gidsz) {
11✔
453
  memset(gid, '\0', gidsz);
11✔
454
  pr_snprintf(gid, gidsz-1, "%lu", (unsigned long) err->err_gid);
11✔
455
  return gid;
11✔
456
}
457

458
/* Returns string of:
459
 *
460
 *  "user ${user} (UID ${uid}, GID ${gid}) via ${protocol}"
461
 */
462
static const char *get_who(pr_error_t *err) {
12✔
463
  const char *who = NULL;
12✔
464

465
  if (error_details & PR_ERROR_DETAILS_USE_NAMES) {
12✔
466
    if (err->err_user != NULL) {
11✔
467
      who = pstrcat(err->err_pool, "user ", err->err_user, NULL);
5✔
468
    }
469

470
    if (error_details & PR_ERROR_DETAILS_USE_IDS) {
11✔
471
      char uid[PR_ERROR_BUFSZ];
472

473
      if (err->err_user != NULL) {
10✔
474
        who = pstrcat(err->err_pool, who,
4✔
475
          " (UID ", get_uid(err, uid, sizeof(uid)), ",", NULL);
476

477
      } else {
478
        who = pstrcat(err->err_pool, "UID ", get_uid(err, uid, sizeof(uid)),
6✔
479
          ",", NULL);
480
      }
481
    }
482

483
    if (error_details & PR_ERROR_DETAILS_USE_IDS) {
11✔
484
      char gid[PR_ERROR_BUFSZ];
485

486
      who = pstrcat(err->err_pool, who, " GID ",
10✔
487
        get_gid(err, gid, sizeof(gid)), NULL);
488
      if (err->err_user != NULL) {
10✔
489
        who = pstrcat(err->err_pool, who, ")", NULL);
4✔
490
      }
491
    }
492

493
  } else if (error_details & PR_ERROR_DETAILS_USE_IDS) {
1✔
494
    char uid[PR_ERROR_BUFSZ], gid[PR_ERROR_BUFSZ];
495

496
    who = pstrcat(err->err_pool, "UID ", get_uid(err, uid, sizeof(uid)),
1✔
497
      ", GID ", get_gid(err, gid, sizeof(gid)), NULL);
498
  }
499

500
  if (error_details & PR_ERROR_DETAILS_USE_PROTOCOL) {
12✔
501
    /* If we don't have a session.user, then we don't have a connection, and
502
     * thus we do not a protocol.
503
     */
504
    if (session.user != NULL) {
11✔
505
      const char *proto;
506

507
      proto = pr_session_get_protocol(0);
5✔
508

509
      if (who != NULL) {
5✔
510
        who = pstrcat(err->err_pool, who, " via ", proto, NULL);
5✔
511

512
      } else {
513
        who = pstrcat(err->err_pool, "via ", proto, NULL);
×
514
      }
515
    }
516
  }
517

518
  return who;
12✔
519
}
520

521
static const char *get_why(pr_error_t *err) {
522
  const char *why = NULL;
12✔
523

524
  if (err->err_goal != NULL) {
12✔
525
    why = err->err_goal;
2✔
526
  }
527

528
  return why;
529
}
530

531
/* Returns string of:
532
 *
533
 *  "${module} [${file}:${lineno}]"
534
 */
535
static const char *get_where(pr_error_t *err) {
12✔
536
  const char *where = NULL;
12✔
537

538
  if (error_details & PR_ERROR_DETAILS_USE_MODULE) {
12✔
539
    if (err->err_module != NULL) {
8✔
540
      where = pstrcat(err->err_pool, "mod_", err->err_module->name, NULL);
1✔
541

542
    } else {
543
      where = pstrdup(err->err_pool, "API");
7✔
544
    }
545
  }
546

547
  if (error_details & PR_ERROR_DETAILS_USE_FILE) {
12✔
548
    if (err->err_file != NULL) {
9✔
549
      int used_brackets = FALSE;
8✔
550

551
      if (where != NULL) {
8✔
552
        where = pstrcat(err->err_pool, where, " [", err->err_file, NULL);
7✔
553
        used_brackets = TRUE;
7✔
554

555
      } else {
556
        where = pstrcat(err->err_pool, err->err_file, NULL);
1✔
557
      }
558

559
      if (err->err_lineno > 0) {
8✔
560
        char linenum[PR_ERROR_BUFSZ];
561

562
        memset(linenum, '\0', sizeof(linenum));
7✔
563
        pr_snprintf(linenum, sizeof(linenum)-1, "%u", err->err_lineno);
7✔
564

565
        where = pstrcat(err->err_pool, where, ":", linenum,
7✔
566
          used_brackets ? "]" : "", NULL);
567

568
      } else {
569
        if (used_brackets) {
1✔
570
          where = pstrcat(err->err_pool, where, "]", NULL);
1✔
571
        }
572
      }
573
    }
574
  }
575

576
  return where;
12✔
577
}
578

579
static const char *get_oper(pr_error_t *err) {
580
  const char *what = NULL;
24✔
581

582
  if (err->err_oper != NULL) {
24✔
583
    what = err->err_oper;
19✔
584
  }
585

586
  return what;
587
}
588

589
static const char *get_what(pr_error_t *err) {
12✔
590
  const char *what = NULL;
12✔
591

592
  if (err->err_oper != NULL) {
12✔
593
    if (err->err_args != NULL) {
7✔
594
      what = pstrcat(err->err_pool, err->err_oper, " using ", err->err_args,
1✔
595
        NULL);
596

597
    } else {
598
      what = err->err_oper;
599
    }
600
  }
601

602
  return what;
12✔
603
}
604

605
/* TODO: Should this be implemented as one large switch statement instead? */
606
static const char *get_errno_name(int xerrno) {
607
  register unsigned int i;
608
  const char *name = NULL;
26✔
609

610
  /* Special-case handling for zero value. */
611
  if (xerrno == 0) {
26✔
612
    return "EOK";
613
  }
614

615
  for (i = 0; errno_names[i].name; i++) {
1,168✔
616
    if (errno_names[i].error_number == xerrno) {
1,192✔
617
      name = errno_names[i].name;
618
      break;
619
    }
620
  }
621

622
  if (name == NULL) {
25✔
623
    name = "<unknown/unsupported error>";
1✔
624
  }
625

626
  return name;
627
}
628

629
static const char *get_errno_desc(int xerrno) {
630
  const char *desc = NULL;
26✔
631

632
  /* Special-case handling for zero value. */
633
  if (xerrno != 0) {
26✔
634
    desc = strerror(xerrno);
25✔
635

636
  } else {
637
    desc = "Success";
638
  }
639

640
  return desc;
641
}
642

643
/* Returns string of:
644
 *
645
 *  "${err_desc} [${err_name} (${err_errno})]"
646
 */
647
static const char *get_failure(pr_error_t *err) {
36✔
648
  const char *failure = NULL;
36✔
649
  char errnum[PR_ERROR_BUFSZ];
650

651
  memset(errnum, '\0', sizeof(errnum));
36✔
652
  pr_snprintf(errnum, sizeof(errnum)-1, "%d", err->err_errno);
36✔
653

654
  if (err->err_name == NULL) {
36✔
655
    err->err_name = get_errno_name(err->err_errno);
52✔
656
  }
657

658
  if (err->err_desc == NULL) {
36✔
659
    err->err_desc = get_errno_desc(err->err_errno);
52✔
660
  }
661

662
  failure = pstrcat(err->err_pool, err->err_desc, " [", err->err_name,
36✔
663
    " (", errnum, ")]", NULL);
664

665
  return failure;
36✔
666
}
667

668
static const char *get_explained(pr_error_t *err) {
669
  const char *explained = NULL;
14✔
670

671
  if (err->err_explained != NULL) {
14✔
672
    explained = err->err_explained;
1✔
673
  }
674

675
  return explained;
676
}
677

678
static const char *get_minimal_text(pool *p, const char *what,
22✔
679
    const char *failure) {
680
  const char *err_text = NULL;
22✔
681

682
  if (what != NULL) {
22✔
683
    err_text = what;
18✔
684
  }
685

686
  if (failure != NULL) {
22✔
687
    if (err_text != NULL) {
22✔
688
      err_text = pstrcat(p, err_text, " failed with \"", failure, "\"", NULL);
18✔
689

690
    } else {
691
      err_text = failure;
692
    }
693
  }
694

695
  return err_text;
22✔
696
}
697

698
static const char *get_terse_text(pool *p, const char *what,
2✔
699
    const char *failure, const char *explained) {
700
  const char *err_text = NULL;
2✔
701

702
  if (what != NULL) {
2✔
703
    err_text = what;
1✔
704
  }
705

706
  if (failure != NULL) {
2✔
707
    /* Not much point in including the failure string if there is no other
708
     * context provided.
709
     */
710
    if (err_text != NULL) {
2✔
711
      err_text = pstrcat(p, err_text, " failed with \"", failure, "\"", NULL);
1✔
712
    }
713
  }
714

715
  if (explained != NULL) {
2✔
716
    /* Not much point in including the failure explanation if there is no
717
     * other context provided.
718
     */
719
    if (err_text != NULL) {
×
720
      err_text = pstrcat(p, err_text, " because ", explained, NULL);
×
721
    }
722
  }
723

724
  return err_text;
2✔
725
}
726

727
static const char *get_detailed_text(pool *p, const char *where,
12✔
728
    const char *who, const char *why, const char *what, const char *failure,
729
    const char *explained) {
730
  const char *err_text = NULL;
12✔
731

732
  if (where != NULL) {
12✔
733
    err_text = pstrcat(p, "in ", where, NULL);
9✔
734
  }
735

736
  if (who != NULL &&
24✔
737
      (what != NULL || where != NULL)) {
12✔
738
    /* Not much point in including who, if there is no what or where to
739
     * go with them.
740
     */
741

742
    if (err_text != NULL) {
11✔
743
      err_text = pstrcat(p, err_text, ", ", who, NULL);
9✔
744

745
    } else {
746
      err_text = who;
747
    }
748
  }
749

750
  if (why != NULL) {
12✔
751
    if (err_text != NULL) {
2✔
752
      err_text = pstrcat(p, err_text, " wanted to ", why, NULL);
2✔
753

754
    } else {
755
      err_text = why;
756
    }
757
  }
758

759
  if (what != NULL) {
12✔
760
    if (err_text != NULL) {
7✔
761
      if (why != NULL) {
7✔
762
        err_text = pstrcat(p, err_text, " but ", what, NULL);
2✔
763

764
      } else {
765
        err_text = pstrcat(p, err_text, " attempting to ", what, NULL);
5✔
766
      }
767

768
    } else {
769
      err_text = what;
770
    }
771
  }
772

773
  if (failure != NULL) {
12✔
774
    /* Not much point in including the failure string if there is no other
775
     * context provided.
776
     */
777
    if (err_text != NULL) {
12✔
778
      err_text = pstrcat(p, err_text, " failed with \"", failure, "\"", NULL);
11✔
779
    }
780
  }
781

782
  if (explained != NULL) {
12✔
783
    /* Not much point in including the failure explanation if there is no
784
     * other context provided.
785
     */
786
    if (err_text != NULL) {
1✔
787
      err_text = pstrcat(p, err_text, " because ", explained, NULL);
1✔
788
    }
789
  }
790

791
  return err_text;
12✔
792
}
793

794
const char *pr_error_strerror(pr_error_t *err, int use_format) {
42✔
795
  const char *err_text = NULL;
42✔
796

797
  if (err == NULL) {
42✔
798
    return strerror(errno);
3✔
799
  }
800

801
  if (use_format == 0) {
39✔
802
    use_format = PR_ERROR_FORMAT_USE_DETAILED;
803
  }
804

805
  switch (use_format) {
36✔
806
    case PR_ERROR_FORMAT_USE_DETAILED:
13✔
807
      if (!(error_formats & PR_ERROR_FORMAT_USE_DETAILED)) {
13✔
808
        use_format = PR_ERROR_FORMAT_USE_TERSE;
809

810
      } else {
811
        break;
812
      }
813

814
    case PR_ERROR_FORMAT_USE_TERSE:
3✔
815
      if (!(error_formats & PR_ERROR_FORMAT_USE_TERSE)) {
3✔
816
        use_format = PR_ERROR_FORMAT_USE_MINIMAL;
817

818
      } else {
819
        break;
820
      }
821

822
    case PR_ERROR_FORMAT_USE_MINIMAL:
823
      break;
824

825
    default:
3✔
826
      /* We want to make sure that pr_error_strerror() ALWAYS returns a
827
       * non-NULL string.  So the fallback behavior is to just use
828
       * normal strerror(3).
829
       */
830
      return strerror(err->err_errno);
3✔
831
  }
832

833
  switch (use_format) {
14✔
834
    case PR_ERROR_FORMAT_USE_DETAILED: {
12✔
835
      const char *who, *why, *where, *what, *failure, *explained;
836

837
      who = get_who(err);
12✔
838
      why = get_why(err);
24✔
839
      where = get_where(err);
12✔
840
      what = get_what(err);
12✔
841
      failure = get_failure(err);
12✔
842
      explained = get_explained(err);
24✔
843

844
      err_text = get_detailed_text(err->err_pool, where, who, why, what,
12✔
845
        failure, explained);
846
      break;
12✔
847
    }
848

849
    case PR_ERROR_FORMAT_USE_TERSE: {
2✔
850
      const char *what, *failure, *explained;
851

852
      /* For terse messages, we only want the operation, if available, and NOT
853
       * the args.
854
       */
855
      what = get_oper(err);
4✔
856
      failure = get_failure(err);
2✔
857
      explained = get_explained(err);
4✔
858

859
      err_text = get_terse_text(err->err_pool, what, failure, explained);
2✔
860
      break;
2✔
861
    }
862

863
    case PR_ERROR_FORMAT_USE_MINIMAL: {
22✔
864
      const char *what, *failure;
865

866
      what = get_oper(err);
44✔
867
      failure = get_failure(err);
22✔
868

869
      err_text = get_minimal_text(err->err_pool, what, failure);
22✔
870
      break;
22✔
871
    }
872

873
    default:
874
      break;
875
  }
876

877
  if (err_text == NULL) {
36✔
878
    return strerror(err->err_errno);
2✔
879
  }
880

881
  return err_text;
882
}
883

884
pr_error_explainer_t *pr_error_register_explainer(pool *p, module *m,
92✔
885
    const char *name) {
886
  struct err_explainer *ee;
887
  pr_error_explainer_t *explainer;
888

889
  if (p == NULL ||
184✔
890
      name == NULL) {
92✔
891
    errno = EINVAL;
2✔
892
    return NULL;
2✔
893
  }
894

895
  /* Check for duplicate registrations. */
896
  if (error_explainers != NULL) {
90✔
897
    for (ee = error_explainers; ee; ee = ee->next) {
×
898
      if ((m == NULL || m == ee->m) &&
2✔
899
          (strcmp(name, ee->name) == 0)) {
1✔
900
        errno = EEXIST;
1✔
901
        return NULL;
1✔
902
      }
903
    }
904
  }
905

906
  ee = pcalloc(p, sizeof(struct err_explainer));
89✔
907
  ee->m = m;
89✔
908
  ee->name = pstrdup(p, name);
89✔
909
  explainer = pcalloc(p, sizeof(pr_error_explainer_t));
89✔
910
  ee->explainer = explainer;
89✔
911

912
  ee->next = error_explainers;
89✔
913
  if (error_explainers != NULL) {
89✔
914
    error_explainers->prev = ee;
×
915

916
  } else {
917
    error_explainers = ee;
89✔
918
  }
919

920
  if (error_explainer == NULL) {
89✔
921
    /* If this is the first set of explainers registered, they become the
922
     * de facto selected set of explainers.
923
     */
924
    error_explainer = ee;
89✔
925
  }
926

927
  return explainer;
928
}
929

930
int pr_error_unregister_explainer(pool *p, module *m, const char *name) {
94✔
931
  struct err_explainer *ee;
932
  int res = -1;
94✔
933

934
  (void) p;
935

936
  /* We need either module or name (or both); both cannot be NULL. */
937
  if (m == NULL &&
188✔
938
      name == NULL) {
94✔
939
    errno = EINVAL;
1✔
940
    return -1;
1✔
941
  }
942

943
  for (ee = error_explainers; ee; ee = ee->next) {
182✔
944
    if ((m == NULL || m == ee->m) &&
89✔
945
        (name == NULL || strcmp(name, ee->name) == 0)) {
71✔
946

947
      if (ee->prev != NULL) {
89✔
948
        ee->prev->next = ee->next;
×
949

950
      } else {
951
        /* This explainer is the head of the explainers list, so we need
952
         * to update the head pointer as well.
953
         */
954
        error_explainers = ee->next;
89✔
955
      }
956

957
      if (ee->next != NULL) {
89✔
958
        ee->next->prev = ee->prev;
×
959
      }
960

961
      ee->prev = ee->next = NULL;
89✔
962

963
      /* If the unregistered explainer is currently the default/selected
964
       * one, make sure to set that pointer to NULL, too.
965
       */
966
      if (ee == error_explainer) {
89✔
967
        error_explainer = NULL;
89✔
968
      }
969

970
      res = 0;
971
    }
972
  }
973

974
  if (res < 0) {
93✔
975
    errno = ENOENT;
4✔
976
  }
977

978
  return res;
979
}
980

981
int pr_error_use_explainer(pool *p, module *m, const char *name) {
5✔
982
  struct err_explainer *ee;
983

984
  (void) p;
985

986
  if (error_explainers == NULL) {
5✔
987
    errno = EPERM;
1✔
988
    return -1;
1✔
989
  }
990

991
  if (name == NULL) {
4✔
992
    errno = EINVAL;
1✔
993
    return -1;
1✔
994
  }
995

996
  if (error_explainer != NULL) {
3✔
997
    if ((m == NULL || m == error_explainer->m) &&
6✔
998
        (strcmp(name, error_explainer->name) == 0)) {
3✔
999
      return 0;
1000
    }
1001
  }
1002

1003
  for (ee = error_explainers; ee; ee = ee->next) {
1✔
1004
    if ((m == NULL || m == ee->m) &&
2✔
1005
        (strcmp(name, ee->name) == 0)) {
1✔
1006
      error_explainer = ee;
×
1007
      return 0;
×
1008
    }
1009
  }
1010

1011
  errno = ENOENT;
1✔
1012
  return -1;
1✔
1013
}
1014

1015
/* Even if err_errno is 0 (OK), we will still call out to the registered
1016
 * explanation providers (explainers).  Why?
1017
 *
1018
 * An explanation provider, not the core API, is responsible for providing
1019
 * a textual description of the operation's arguments, if nothing else.  Thus
1020
 * even for an "OK" errno value, the caller might want the full textual
1021
 * description of the operation and its arguments.
1022
 */
1023

1024
static void trace_explained_error(const char *what, int xerrno) {
136✔
1025
  if (error_explainer->m != NULL) {
136✔
1026
    (void) pr_trace_msg(trace_channel, 9,
272✔
1027
      "'%s' explanations (from mod_%s), failed to explain '%s': %s",
1028
      error_explainer->name, error_explainer->m->name, what, strerror(xerrno));
136✔
1029

1030
  } else {
1031
    pr_trace_msg(trace_channel, 9,
×
1032
      "'%s' explanations (from API), failed to explain '%s': %s",
1033
      error_explainer->name, what, strerror(xerrno));
×
1034
  }
1035
}
136✔
1036

1037
static int check_error(pr_error_t *err) {
376✔
1038
  if (err == NULL) {
376✔
1039
    errno = EINVAL;
68✔
1040
    return -1;
68✔
1041
  }
1042

1043
  if (error_explainer == NULL) {
308✔
1044
    errno = ENOSYS;
87✔
1045
    return -1;
87✔
1046
  }
1047

1048
  return 0;
1049
}
1050

1051
int pr_error_explain_accept(pr_error_t *err, int fd, struct sockaddr *addr,
5✔
1052
    socklen_t *addr_len) {
1053
  const char *what = "accept()", *explained = NULL;
5✔
1054
  int xerrno = ENOSYS;
5✔
1055

1056
  if (check_error(err) < 0) {
5✔
1057
    return -1;
1058
  }
1059

1060
  (void) pr_error_set_why(err, what);
3✔
1061

1062
  if (error_explainer->explainer->explain_accept != NULL) {
3✔
1063
    explained = (error_explainer->explainer->explain_accept)(err->err_pool,
2✔
1064
      err->err_errno, fd, addr, addr_len, &(err->err_args));
1065
    xerrno = errno;
2✔
1066
  }
1067

1068
  if (explained == NULL) {
2✔
1069
    trace_explained_error(what, xerrno);
2✔
1070
    errno = xerrno;
2✔
1071
    return -1;
2✔
1072
  }
1073

1074
  err->err_explained = explained;
1✔
1075
  return 0;
1✔
1076
}
1077

1078
int pr_error_explain_bind(pr_error_t *err, int fd, const struct sockaddr *addr,
5✔
1079
    socklen_t addr_len) {
1080
  const char *what = "bind()", *explained = NULL;
5✔
1081
  int xerrno = ENOSYS;
5✔
1082

1083
  if (check_error(err) < 0) {
5✔
1084
    return -1;
1085
  }
1086

1087
  (void) pr_error_set_what(err, what);
3✔
1088

1089
  if (error_explainer->explainer->explain_bind != NULL) {
3✔
1090
    explained = (error_explainer->explainer->explain_bind)(err->err_pool,
2✔
1091
      err->err_errno, fd, addr, addr_len, &(err->err_args));
1092
    xerrno = errno;
2✔
1093
  }
1094

1095
  if (explained == NULL) {
2✔
1096
    trace_explained_error(what, xerrno);
2✔
1097
    errno = xerrno;
2✔
1098
    return -1;
2✔
1099
  }
1100

1101
  err->err_explained = explained;
1✔
1102
  return 0;
1✔
1103
}
1104

1105
int pr_error_explain_chdir(pr_error_t *err, const char *path) {
5✔
1106
  const char *what = "chdir()", *explained = NULL;
5✔
1107
  int xerrno = ENOSYS;
5✔
1108

1109
  if (check_error(err) < 0) {
5✔
1110
    return -1;
1111
  }
1112

1113
  (void) pr_error_set_what(err, what);
3✔
1114

1115
  if (error_explainer->explainer->explain_chdir != NULL) {
3✔
1116
    explained = (error_explainer->explainer->explain_chdir)(err->err_pool,
2✔
1117
      err->err_errno, path, &(err->err_args));
1118
    xerrno = errno;
2✔
1119
  }
1120

1121
  if (explained == NULL) {
2✔
1122
    trace_explained_error(what, xerrno);
2✔
1123
    errno = xerrno;
2✔
1124
    return -1;
2✔
1125
  }
1126

1127
  err->err_explained = explained;
1✔
1128
  return 0;
1✔
1129
}
1130

1131
int pr_error_explain_chmod(pr_error_t *err, const char *path, mode_t mode) {
7✔
1132
  const char *what = "chmod()", *explained = NULL;
7✔
1133
  int xerrno = ENOSYS;
7✔
1134

1135
  if (check_error(err) < 0) {
7✔
1136
    return -1;
1137
  }
1138

1139
  (void) pr_error_set_what(err, what);
4✔
1140

1141
  if (error_explainer->explainer->explain_chmod != NULL) {
4✔
1142
    explained = (error_explainer->explainer->explain_chmod)(err->err_pool,
3✔
1143
      err->err_errno, path, mode, &(err->err_args));
1144
    xerrno = errno;
3✔
1145
  }
1146

1147
  if (explained == NULL) {
3✔
1148
    trace_explained_error(what, xerrno);
2✔
1149
    errno = xerrno;
2✔
1150
    return -1;
2✔
1151
  }
1152

1153
  err->err_explained = explained;
2✔
1154
  return 0;
2✔
1155
}
1156

1157
int pr_error_explain_chown(pr_error_t *err, const char *path, uid_t uid,
7✔
1158
    gid_t gid) {
1159
  const char *what = "chown()", *explained = NULL;
7✔
1160
  int xerrno = ENOSYS;
7✔
1161

1162
  if (check_error(err) < 0) {
7✔
1163
    return -1;
1164
  }
1165

1166
  (void) pr_error_set_what(err, what);
4✔
1167

1168
  if (error_explainer->explainer->explain_chown != NULL) {
4✔
1169
    explained = (error_explainer->explainer->explain_chown)(err->err_pool,
3✔
1170
      err->err_errno, path, uid, gid, &(err->err_args));
1171
    xerrno = errno;
3✔
1172
  }
1173

1174
  if (explained == NULL) {
3✔
1175
    trace_explained_error(what, xerrno);
2✔
1176
    errno = xerrno;
2✔
1177
    return -1;
2✔
1178
  }
1179

1180
  err->err_explained = explained;
2✔
1181
  return 0;
2✔
1182
}
1183

1184
int pr_error_explain_chroot(pr_error_t *err, const char *path) {
11✔
1185
  const char *what = "chroot()", *explained = NULL;
11✔
1186
  int xerrno = ENOSYS;
11✔
1187

1188
  if (check_error(err) < 0) {
11✔
1189
    return -1;
1190
  }
1191

1192
  (void) pr_error_set_what(err, what);
4✔
1193

1194
  if (error_explainer->explainer->explain_chroot != NULL) {
4✔
1195
    explained = (error_explainer->explainer->explain_chroot)(err->err_pool,
3✔
1196
      err->err_errno, path, &(err->err_args));
1197
    xerrno = errno;
3✔
1198
  }
1199

1200
  if (explained == NULL) {
3✔
1201
    trace_explained_error(what, xerrno);
2✔
1202
    errno = xerrno;
2✔
1203
    return -1;
2✔
1204
  }
1205

1206
  err->err_explained = explained;
2✔
1207
  return 0;
2✔
1208
}
1209

1210
int pr_error_explain_close(pr_error_t *err, int fd) {
7✔
1211
  const char *what = "close()", *explained = NULL;
7✔
1212
  int xerrno = ENOSYS;
7✔
1213

1214
  if (check_error(err) < 0) {
7✔
1215
    return -1;
1216
  }
1217

1218
  (void) pr_error_set_what(err, what);
4✔
1219

1220
  if (error_explainer->explainer->explain_close != NULL) {
4✔
1221
    explained = (error_explainer->explainer->explain_close)(err->err_pool,
3✔
1222
      err->err_errno, fd, &(err->err_args));
1223
    xerrno = errno;
3✔
1224
  }
1225

1226
  if (explained == NULL) {
3✔
1227
    trace_explained_error(what, xerrno);
2✔
1228
    errno = xerrno;
2✔
1229
    return -1;
2✔
1230
  }
1231

1232
  err->err_explained = explained;
2✔
1233
  return 0;
2✔
1234
}
1235

1236
int pr_error_explain_closedir(pr_error_t *err, void *dirh) {
5✔
1237
  const char *what = "closedir()", *explained = NULL;
5✔
1238
  int xerrno = ENOSYS;
5✔
1239

1240
  if (check_error(err) < 0) {
5✔
1241
    return -1;
1242
  }
1243

1244
  (void) pr_error_set_what(err, what);
3✔
1245

1246
  if (error_explainer->explainer->explain_closedir != NULL) {
3✔
1247
    explained = (error_explainer->explainer->explain_closedir)(err->err_pool,
2✔
1248
      err->err_errno, dirh, &(err->err_args));
1249
    xerrno = errno;
2✔
1250
  }
1251

1252
  if (explained == NULL) {
2✔
1253
    trace_explained_error(what, xerrno);
2✔
1254
    errno = xerrno;
2✔
1255
    return -1;
2✔
1256
  }
1257

1258
  err->err_explained = explained;
1✔
1259
  return 0;
1✔
1260
}
1261

1262
int pr_error_explain_connect(pr_error_t *err, int fd,
5✔
1263
    const struct sockaddr *addr, socklen_t addr_len) {
1264
  const char *what = "connect()", *explained = NULL;
5✔
1265
  int xerrno = ENOSYS;
5✔
1266

1267
  if (check_error(err) < 0) {
5✔
1268
    return -1;
1269
  }
1270

1271
  (void) pr_error_set_what(err, what);
3✔
1272

1273
  if (error_explainer->explainer->explain_connect != NULL) {
3✔
1274
    explained = (error_explainer->explainer->explain_connect)(err->err_pool,
2✔
1275
      err->err_errno, fd, addr, addr_len, &(err->err_args));
1276
    xerrno = errno;
2✔
1277
  }
1278

1279
  if (explained == NULL) {
2✔
1280
    trace_explained_error(what, xerrno);
2✔
1281
    errno = xerrno;
2✔
1282
    return -1;
2✔
1283
  }
1284

1285
  err->err_explained = explained;
1✔
1286
  return 0;
1✔
1287
}
1288

1289
int pr_error_explain_fchmod(pr_error_t *err, int fd, mode_t mode) {
7✔
1290
  const char *what = "fchmod()", *explained = NULL;
7✔
1291
  int xerrno = ENOSYS;
7✔
1292

1293
  if (check_error(err) < 0) {
7✔
1294
    return -1;
1295
  }
1296

1297
  (void) pr_error_set_what(err, what);
4✔
1298

1299
  if (error_explainer->explainer->explain_fchmod != NULL) {
4✔
1300
    explained = (error_explainer->explainer->explain_fchmod)(err->err_pool,
3✔
1301
      err->err_errno, fd, mode, &(err->err_args));
1302
    xerrno = errno;
3✔
1303
  }
1304

1305
  if (explained == NULL) {
3✔
1306
    trace_explained_error(what, xerrno);
2✔
1307
    errno = xerrno;
2✔
1308
    return -1;
2✔
1309
  }
1310

1311
  err->err_explained = explained;
2✔
1312
  return 0;
2✔
1313
}
1314

1315
int pr_error_explain_fchown(pr_error_t *err, int fd, uid_t uid, gid_t gid) {
7✔
1316
  const char *what = "fchown()", *explained = NULL;
7✔
1317
  int xerrno = ENOSYS;
7✔
1318

1319
  if (check_error(err) < 0) {
7✔
1320
    return -1;
1321
  }
1322

1323
  (void) pr_error_set_what(err, what);
4✔
1324

1325
  if (error_explainer->explainer->explain_fchown != NULL) {
4✔
1326
    explained = (error_explainer->explainer->explain_fchown)(err->err_pool,
3✔
1327
      err->err_errno, fd, uid, gid, &(err->err_args));
1328
    xerrno = errno;
3✔
1329
  }
1330

1331
  if (explained == NULL) {
3✔
1332
    trace_explained_error(what, xerrno);
2✔
1333
    errno = xerrno;
2✔
1334
    return -1;
2✔
1335
  }
1336

1337
  err->err_explained = explained;
2✔
1338
  return 0;
2✔
1339
}
1340

1341
int pr_error_explain_fclose(pr_error_t *err, FILE *fh) {
5✔
1342
  const char *what = "fclose()", *explained = NULL;
5✔
1343
  int xerrno = ENOSYS;
5✔
1344

1345
  if (check_error(err) < 0) {
5✔
1346
    return -1;
1347
  }
1348

1349
  (void) pr_error_set_what(err, what);
3✔
1350

1351
  if (error_explainer->explainer->explain_fclose != NULL) {
3✔
1352
    explained = (error_explainer->explainer->explain_fclose)(err->err_pool,
2✔
1353
      err->err_errno, fh, &(err->err_args));
1354
    xerrno = errno;
2✔
1355
  }
1356

1357
  if (explained == NULL) {
2✔
1358
    trace_explained_error(what, xerrno);
2✔
1359
    errno = xerrno;
2✔
1360
    return -1;
2✔
1361
  }
1362

1363
  err->err_explained = explained;
1✔
1364
  return 0;
1✔
1365
}
1366

1367
int pr_error_explain_fcntl(pr_error_t *err, int fd, int op, long arg) {
5✔
1368
  const char *what = "fcntl()", *explained = NULL;
5✔
1369
  int xerrno = ENOSYS;
5✔
1370

1371
  if (check_error(err) < 0) {
5✔
1372
    return -1;
1373
  }
1374

1375
  (void) pr_error_set_what(err, what);
3✔
1376

1377
  if (error_explainer->explainer->explain_fcntl != NULL) {
3✔
1378
    explained = (error_explainer->explainer->explain_fcntl)(err->err_pool,
2✔
1379
      err->err_errno, fd, op, arg, &(err->err_args));
1380
    xerrno = errno;
2✔
1381
  }
1382

1383
  if (explained == NULL) {
2✔
1384
    trace_explained_error(what, xerrno);
2✔
1385
    errno = xerrno;
2✔
1386
    return -1;
2✔
1387
  }
1388

1389
  err->err_explained = explained;
1✔
1390
  return 0;
1✔
1391
}
1392

1393
int pr_error_explain_fdopen(pr_error_t *err, int fd, const char *mode) {
5✔
1394
  const char *what = "fdopen()", *explained = NULL;
5✔
1395
  int xerrno = ENOSYS;
5✔
1396

1397
  if (check_error(err) < 0) {
5✔
1398
    return -1;
1399
  }
1400

1401
  (void) pr_error_set_what(err, what);
3✔
1402

1403
  if (error_explainer->explainer->explain_fdopen != NULL) {
3✔
1404
    explained = (error_explainer->explainer->explain_fdopen)(err->err_pool,
2✔
1405
      err->err_errno, fd, mode, &(err->err_args));
1406
    xerrno = errno;
2✔
1407
  }
1408

1409
  if (explained == NULL) {
2✔
1410
    trace_explained_error(what, xerrno);
2✔
1411
    errno = xerrno;
2✔
1412
    return -1;
2✔
1413
  }
1414

1415
  err->err_explained = explained;
1✔
1416
  return 0;
1✔
1417
}
1418

1419
int pr_error_explain_flock(pr_error_t *err, int fd, int op) {
5✔
1420
  const char *what = "flock()", *explained = NULL;
5✔
1421
  int xerrno = ENOSYS;
5✔
1422

1423
  if (check_error(err) < 0) {
5✔
1424
    return -1;
1425
  }
1426

1427
  (void) pr_error_set_what(err, what);
3✔
1428

1429
  if (error_explainer->explainer->explain_flock != NULL) {
3✔
1430
    explained = (error_explainer->explainer->explain_flock)(err->err_pool,
2✔
1431
      err->err_errno, fd, op, &(err->err_args));
1432
    xerrno = errno;
2✔
1433
  }
1434

1435
  if (explained == NULL) {
2✔
1436
    trace_explained_error(what, xerrno);
2✔
1437
    errno = xerrno;
2✔
1438
    return -1;
2✔
1439
  }
1440

1441
  err->err_explained = explained;
1✔
1442
  return 0;
1✔
1443
}
1444

1445
int pr_error_explain_fopen(pr_error_t *err, const char *path,
5✔
1446
    const char *mode) {
1447
  const char *what = "fopen()", *explained = NULL;
5✔
1448
  int xerrno = ENOSYS;
5✔
1449

1450
  if (check_error(err) < 0) {
5✔
1451
    return -1;
1452
  }
1453

1454
  (void) pr_error_set_what(err, what);
3✔
1455

1456
  if (error_explainer->explainer->explain_fopen != NULL) {
3✔
1457
    explained = (error_explainer->explainer->explain_fopen)(err->err_pool,
2✔
1458
      err->err_errno, path, mode, &(err->err_args));
1459
    xerrno = errno;
2✔
1460
  }
1461

1462
  if (explained == NULL) {
2✔
1463
    trace_explained_error(what, xerrno);
2✔
1464
    errno = xerrno;
2✔
1465
    return -1;
2✔
1466
  }
1467

1468
  err->err_explained = explained;
1✔
1469
  return 0;
1✔
1470
}
1471

1472
int pr_error_explain_fork(pr_error_t *err) {
5✔
1473
  const char *what = "fork()", *explained = NULL;
5✔
1474
  int xerrno = ENOSYS;
5✔
1475

1476
  if (check_error(err) < 0) {
5✔
1477
    return -1;
1478
  }
1479

1480
  (void) pr_error_set_what(err, what);
3✔
1481

1482
  if (error_explainer->explainer->explain_fork != NULL) {
3✔
1483
    explained = (error_explainer->explainer->explain_fork)(err->err_pool,
2✔
1484
      err->err_errno, &(err->err_args));
1485
    xerrno = errno;
2✔
1486
  }
1487

1488
  if (explained == NULL) {
2✔
1489
    trace_explained_error(what, xerrno);
2✔
1490
    errno = xerrno;
2✔
1491
    return -1;
2✔
1492
  }
1493

1494
  err->err_explained = explained;
1✔
1495
  return 0;
1✔
1496
}
1497

1498
int pr_error_explain_fstat(pr_error_t *err, int fd, struct stat *st) {
5✔
1499
  const char *what = "fstat()", *explained = NULL;
5✔
1500
  int xerrno = ENOSYS;
5✔
1501

1502
  if (check_error(err) < 0) {
5✔
1503
    return -1;
1504
  }
1505

1506
  (void) pr_error_set_what(err, what);
3✔
1507

1508
  if (error_explainer->explainer->explain_fstat != NULL) {
3✔
1509
    explained = (error_explainer->explainer->explain_fstat)(err->err_pool,
2✔
1510
      err->err_errno, fd, st, &(err->err_args));
1511
    xerrno = errno;
2✔
1512
  }
1513

1514
  if (explained == NULL) {
2✔
1515
    trace_explained_error(what, xerrno);
2✔
1516
    errno = xerrno;
2✔
1517
    return -1;
2✔
1518
  }
1519

1520
  err->err_explained = explained;
1✔
1521
  return 0;
1✔
1522
}
1523

1524
int pr_error_explain_fstatfs(pr_error_t *err, int fd, void *stfs) {
5✔
1525
  const char *what = "fstatfs()", *explained = NULL;
5✔
1526
  int xerrno = ENOSYS;
5✔
1527

1528
  if (check_error(err) < 0) {
5✔
1529
    return -1;
1530
  }
1531

1532
  (void) pr_error_set_what(err, what);
3✔
1533

1534
  if (error_explainer->explainer->explain_fstatfs != NULL) {
3✔
1535
    explained = (error_explainer->explainer->explain_fstatfs)(err->err_pool,
2✔
1536
      err->err_errno, fd, stfs, &(err->err_args));
1537
    xerrno = errno;
2✔
1538
  }
1539

1540
  if (explained == NULL) {
2✔
1541
    trace_explained_error(what, xerrno);
2✔
1542
    errno = xerrno;
2✔
1543
    return -1;
2✔
1544
  }
1545

1546
  err->err_explained = explained;
1✔
1547
  return 0;
1✔
1548
}
1549

1550
int pr_error_explain_fstatvfs(pr_error_t *err, int fd, void *stfs) {
5✔
1551
  const char *what = "fstatvfs()", *explained = NULL;
5✔
1552
  int xerrno = ENOSYS;
5✔
1553

1554
  if (check_error(err) < 0) {
5✔
1555
    return -1;
1556
  }
1557

1558
  (void) pr_error_set_what(err, what);
3✔
1559

1560
  if (error_explainer->explainer->explain_fstatvfs != NULL) {
3✔
1561
    explained = (error_explainer->explainer->explain_fstatvfs)(err->err_pool,
2✔
1562
      err->err_errno, fd, stfs, &(err->err_args));
1563
    xerrno = errno;
2✔
1564
  }
1565

1566
  if (explained == NULL) {
2✔
1567
    trace_explained_error(what, xerrno);
2✔
1568
    errno = xerrno;
2✔
1569
    return -1;
2✔
1570
  }
1571

1572
  err->err_explained = explained;
1✔
1573
  return 0;
1✔
1574
}
1575

1576
int pr_error_explain_fsync(pr_error_t *err, int fd) {
5✔
1577
  const char *what = "fsync()", *explained = NULL;
5✔
1578
  int xerrno = ENOSYS;
5✔
1579

1580
  if (check_error(err) < 0) {
5✔
1581
    return -1;
1582
  }
1583

1584
  (void) pr_error_set_what(err, what);
3✔
1585

1586
  if (error_explainer->explainer->explain_fsync != NULL) {
3✔
1587
    explained = (error_explainer->explainer->explain_fsync)(err->err_pool,
2✔
1588
      err->err_errno, fd, &(err->err_args));
1589
    xerrno = errno;
2✔
1590
  }
1591

1592
  if (explained == NULL) {
2✔
1593
    trace_explained_error(what, xerrno);
2✔
1594
    errno = xerrno;
2✔
1595
    return -1;
2✔
1596
  }
1597

1598
  err->err_explained = explained;
1✔
1599
  return 0;
1✔
1600
}
1601

1602
int pr_error_explain_ftruncate(pr_error_t *err, int fd, off_t len) {
5✔
1603
  const char *what = "ftruncate()", *explained = NULL;
5✔
1604
  int xerrno = ENOSYS;
5✔
1605

1606
  if (check_error(err) < 0) {
5✔
1607
    return -1;
1608
  }
1609

1610
  (void) pr_error_set_what(err, what);
3✔
1611

1612
  if (error_explainer->explainer->explain_ftruncate != NULL) {
3✔
1613
    explained = (error_explainer->explainer->explain_ftruncate)(
2✔
1614
      err->err_pool, err->err_errno, fd, len, &(err->err_args));
1615
    xerrno = errno;
2✔
1616
  }
1617

1618
  if (explained == NULL) {
2✔
1619
    trace_explained_error(what, xerrno);
2✔
1620
    errno = xerrno;
2✔
1621
    return -1;
2✔
1622
  }
1623

1624
  err->err_explained = explained;
1✔
1625
  return 0;
1✔
1626
}
1627

1628
int pr_error_explain_futimes(pr_error_t *err, int fd,
5✔
1629
    const struct timeval *tvs) {
1630
  const char *what = "futimes()", *explained = NULL;
5✔
1631
  int xerrno = ENOSYS;
5✔
1632

1633
  if (check_error(err) < 0) {
5✔
1634
    return -1;
1635
  }
1636

1637
  (void) pr_error_set_what(err, what);
3✔
1638

1639
  if (error_explainer->explainer->explain_futimes != NULL) {
3✔
1640
    explained = (error_explainer->explainer->explain_futimes)(err->err_pool,
2✔
1641
      err->err_errno, fd, tvs, &(err->err_args));
1642
    xerrno = errno;
2✔
1643
  }
1644

1645
  if (explained == NULL) {
2✔
1646
    trace_explained_error(what, xerrno);
2✔
1647
    errno = xerrno;
2✔
1648
    return -1;
2✔
1649
  }
1650

1651
  err->err_explained = explained;
1✔
1652
  return 0;
1✔
1653
}
1654

1655
int pr_error_explain_getaddrinfo(pr_error_t *err, const char *name,
5✔
1656
    const char *service, const struct addrinfo *hints, struct addrinfo **res) {
1657
  const char *what = "getaddrinfo()", *explained = NULL;
5✔
1658
  int xerrno = ENOSYS;
5✔
1659

1660
  if (check_error(err) < 0) {
5✔
1661
    return -1;
1662
  }
1663

1664
  (void) pr_error_set_what(err, what);
3✔
1665

1666
  if (error_explainer->explainer->explain_getaddrinfo != NULL) {
3✔
1667
    explained = (error_explainer->explainer->explain_getaddrinfo)(
2✔
1668
      err->err_pool, err->err_errno, name, service, hints, res,
1669
      &(err->err_args));
1670
    xerrno = errno;
2✔
1671
  }
1672

1673
  if (explained == NULL) {
2✔
1674
    trace_explained_error(what, xerrno);
2✔
1675
    errno = xerrno;
2✔
1676
    return -1;
2✔
1677
  }
1678

1679
  err->err_explained = explained;
1✔
1680
  return 0;
1✔
1681
}
1682

1683
int pr_error_explain_gethostbyname(pr_error_t *err, const char *name) {
5✔
1684
  const char *what = "gethostbyname()", *explained = NULL;
5✔
1685
  int xerrno = ENOSYS;
5✔
1686

1687
  if (check_error(err) < 0) {
5✔
1688
    return -1;
1689
  }
1690

1691
  (void) pr_error_set_what(err, what);
3✔
1692

1693
  if (error_explainer->explainer->explain_gethostbyname != NULL) {
3✔
1694
    explained = (error_explainer->explainer->explain_gethostbyname)(
2✔
1695
      err->err_pool, err->err_errno, name, &(err->err_args));
1696
    xerrno = errno;
2✔
1697
  }
1698

1699
  if (explained == NULL) {
2✔
1700
    trace_explained_error(what, xerrno);
2✔
1701
    errno = xerrno;
2✔
1702
    return -1;
2✔
1703
  }
1704

1705
  err->err_explained = explained;
1✔
1706
  return 0;
1✔
1707
}
1708

1709
int pr_error_explain_gethostbyname2(pr_error_t *err, const char *name,
5✔
1710
    int family) {
1711
  const char *what = "gethostbyname2()", *explained = NULL;
5✔
1712
  int xerrno = ENOSYS;
5✔
1713

1714
  if (check_error(err) < 0) {
5✔
1715
    return -1;
1716
  }
1717

1718
  (void) pr_error_set_what(err, what);
3✔
1719

1720
  if (error_explainer->explainer->explain_gethostbyname2 != NULL) {
3✔
1721
    explained = (error_explainer->explainer->explain_gethostbyname2)(
2✔
1722
      err->err_pool, err->err_errno, name, family, &(err->err_args));
1723
    xerrno = errno;
2✔
1724
  }
1725

1726
  if (explained == NULL) {
2✔
1727
    trace_explained_error(what, xerrno);
2✔
1728
    errno = xerrno;
2✔
1729
    return -1;
2✔
1730
  }
1731

1732
  err->err_explained = explained;
1✔
1733
  return 0;
1✔
1734
}
1735

1736
int pr_error_explain_gethostname(pr_error_t *err, char *buf, size_t sz) {
5✔
1737
  const char *what = "gethostname()", *explained = NULL;
5✔
1738
  int xerrno = ENOSYS;
5✔
1739

1740
  if (check_error(err) < 0) {
5✔
1741
    return -1;
1742
  }
1743

1744
  (void) pr_error_set_what(err, what);
3✔
1745

1746
  if (error_explainer->explainer->explain_gethostname != NULL) {
3✔
1747
    explained = (error_explainer->explainer->explain_gethostname)(
2✔
1748
      err->err_pool, err->err_errno, buf, sz, &(err->err_args));
1749
    xerrno = errno;
2✔
1750
  }
1751

1752
  if (explained == NULL) {
2✔
1753
    trace_explained_error(what, xerrno);
2✔
1754
    errno = xerrno;
2✔
1755
    return -1;
2✔
1756
  }
1757

1758
  err->err_explained = explained;
1✔
1759
  return 0;
1✔
1760
}
1761

1762
int pr_error_explain_getnameinfo(pr_error_t *err, const struct sockaddr *addr,
5✔
1763
    socklen_t addr_len, char *host, size_t host_len, char *service,
1764
    size_t service_len, int flags) {
1765
  const char *what = "getnameinfo()", *explained = NULL;
5✔
1766
  int xerrno = ENOSYS;
5✔
1767

1768
  if (check_error(err) < 0) {
5✔
1769
    return -1;
1770
  }
1771

1772
  (void) pr_error_set_what(err, what);
3✔
1773

1774
  if (error_explainer->explainer->explain_getnameinfo != NULL) {
3✔
1775
    explained = (error_explainer->explainer->explain_getnameinfo)(
2✔
1776
      err->err_pool, err->err_errno, addr, addr_len, host, host_len, service,
1777
      service_len, flags, &(err->err_args));
1778
    xerrno = errno;
2✔
1779
  }
1780

1781
  if (explained == NULL) {
2✔
1782
    trace_explained_error(what, xerrno);
2✔
1783
    errno = xerrno;
2✔
1784
    return -1;
2✔
1785
  }
1786

1787
  err->err_explained = explained;
1✔
1788
  return 0;
1✔
1789
}
1790

1791
int pr_error_explain_getpeername(pr_error_t *err, int fd, struct sockaddr *addr,
5✔
1792
    socklen_t *addr_len) {
1793
  const char *what = "getpeername()", *explained = NULL;
5✔
1794
  int xerrno = ENOSYS;
5✔
1795

1796
  if (check_error(err) < 0) {
5✔
1797
    return -1;
1798
  }
1799

1800
  (void) pr_error_set_what(err, what);
3✔
1801

1802
  if (error_explainer->explainer->explain_getpeername != NULL) {
3✔
1803
    explained = (error_explainer->explainer->explain_getpeername)(
2✔
1804
      err->err_pool, err->err_errno, fd, addr, addr_len, &(err->err_args));
1805
    xerrno = errno;
2✔
1806
  }
1807

1808
  if (explained == NULL) {
2✔
1809
    trace_explained_error(what, xerrno);
2✔
1810
    errno = xerrno;
2✔
1811
    return -1;
2✔
1812
  }
1813

1814
  err->err_explained = explained;
1✔
1815
  return 0;
1✔
1816
}
1817

1818
int pr_error_explain_getrlimit(pr_error_t *err, int resource,
5✔
1819
    struct rlimit *rlim) {
1820
  const char *what = "getrlimit()", *explained = NULL;
5✔
1821
  int xerrno = ENOSYS;
5✔
1822

1823
  if (check_error(err) < 0) {
5✔
1824
    return -1;
1825
  }
1826

1827
  (void) pr_error_set_what(err, what);
3✔
1828

1829
  if (error_explainer->explainer->explain_getrlimit != NULL) {
3✔
1830
    explained = (error_explainer->explainer->explain_getrlimit)(
2✔
1831
      err->err_pool, err->err_errno, resource, rlim, &(err->err_args));
1832
    xerrno = errno;
2✔
1833
  }
1834

1835
  if (explained == NULL) {
2✔
1836
    trace_explained_error(what, xerrno);
2✔
1837
    errno = xerrno;
2✔
1838
    return -1;
2✔
1839
  }
1840

1841
  err->err_explained = explained;
1✔
1842
  return 0;
1✔
1843
}
1844

1845
int pr_error_explain_getsockname(pr_error_t *err, int fd, struct sockaddr *addr,
5✔
1846
    socklen_t *addr_len) {
1847
  const char *what = "getsockname()", *explained = NULL;
5✔
1848
  int xerrno = ENOSYS;
5✔
1849

1850
  if (check_error(err) < 0) {
5✔
1851
    return -1;
1852
  }
1853

1854
  (void) pr_error_set_what(err, what);
3✔
1855

1856
  if (error_explainer->explainer->explain_getsockname != NULL) {
3✔
1857
    explained = (error_explainer->explainer->explain_getsockname)(
2✔
1858
      err->err_pool, err->err_errno, fd, addr, addr_len, &(err->err_args));
1859
    xerrno = errno;
2✔
1860
  }
1861

1862
  if (explained == NULL) {
2✔
1863
    trace_explained_error(what, xerrno);
2✔
1864
    errno = xerrno;
2✔
1865
    return -1;
2✔
1866
  }
1867

1868
  err->err_explained = explained;
1✔
1869
  return 0;
1✔
1870
}
1871

1872
int pr_error_explain_getsockopt(pr_error_t *err, int fd, int level, int option,
5✔
1873
    void *val, socklen_t *valsz) {
1874
  const char *what = "getsockopt()", *explained = NULL;
5✔
1875
  int xerrno = ENOSYS;
5✔
1876

1877
  if (check_error(err) < 0) {
5✔
1878
    return -1;
1879
  }
1880

1881
  (void) pr_error_set_what(err, what);
3✔
1882

1883
  if (error_explainer->explainer->explain_getsockopt != NULL) {
3✔
1884
    explained = (error_explainer->explainer->explain_getsockopt)(
2✔
1885
      err->err_pool, err->err_errno, fd, level, option, val, valsz,
1886
      &(err->err_args));
1887
    xerrno = errno;
2✔
1888
  }
1889

1890
  if (explained == NULL) {
2✔
1891
    trace_explained_error(what, xerrno);
2✔
1892
    errno = xerrno;
2✔
1893
    return -1;
2✔
1894
  }
1895

1896
  err->err_explained = explained;
1✔
1897
  return 0;
1✔
1898
}
1899

1900
int pr_error_explain_lchown(pr_error_t *err, const char *path, uid_t uid,
7✔
1901
    gid_t gid) {
1902
  const char *what = "lchown()", *explained = NULL;
7✔
1903
  int xerrno = ENOSYS;
7✔
1904

1905
  if (check_error(err) < 0) {
7✔
1906
    return -1;
1907
  }
1908

1909
  (void) pr_error_set_what(err, what);
4✔
1910

1911
  if (error_explainer->explainer->explain_lchown != NULL) {
4✔
1912
    explained = (error_explainer->explainer->explain_lchown)(err->err_pool,
3✔
1913
      err->err_errno, path, uid, gid, &(err->err_args));
1914
    xerrno = errno;
3✔
1915
  }
1916

1917
  if (explained == NULL) {
3✔
1918
    trace_explained_error(what, xerrno);
2✔
1919
    errno = xerrno;
2✔
1920
    return -1;
2✔
1921
  }
1922

1923
  err->err_explained = explained;
2✔
1924
  return 0;
2✔
1925
}
1926

1927
int pr_error_explain_link(pr_error_t *err, const char *target_path,
5✔
1928
    const char *link_path) {
1929
  const char *what = "link()", *explained = NULL;
5✔
1930
  int xerrno = ENOSYS;
5✔
1931

1932
  if (check_error(err) < 0) {
5✔
1933
    return -1;
1934
  }
1935

1936
  (void) pr_error_set_what(err, what);
3✔
1937

1938
  if (error_explainer->explainer->explain_link != NULL) {
3✔
1939
    explained = (error_explainer->explainer->explain_link)(err->err_pool,
2✔
1940
      err->err_errno, target_path, link_path, &(err->err_args));
1941
    xerrno = errno;
2✔
1942
  }
1943

1944
  if (explained == NULL) {
2✔
1945
    trace_explained_error(what, xerrno);
2✔
1946
    errno = xerrno;
2✔
1947
    return -1;
2✔
1948
  }
1949

1950
  err->err_explained = explained;
1✔
1951
  return 0;
1✔
1952
}
1953

1954
int pr_error_explain_listen(pr_error_t *err, int fd, int backlog) {
5✔
1955
  const char *what = "listen()", *explained = NULL;
5✔
1956
  int xerrno = ENOSYS;
5✔
1957

1958
  if (check_error(err) < 0) {
5✔
1959
    return -1;
1960
  }
1961

1962
  (void) pr_error_set_what(err, what);
3✔
1963

1964
  if (error_explainer->explainer->explain_listen != NULL) {
3✔
1965
    explained = (error_explainer->explainer->explain_listen)(err->err_pool,
2✔
1966
      err->err_errno, fd, backlog, &(err->err_args));
1967
    xerrno = errno;
2✔
1968
  }
1969

1970
  if (explained == NULL) {
2✔
1971
    trace_explained_error(what, xerrno);
2✔
1972
    errno = xerrno;
2✔
1973
    return -1;
2✔
1974
  }
1975

1976
  err->err_explained = explained;
1✔
1977
  return 0;
1✔
1978
}
1979

1980
int pr_error_explain_lseek(pr_error_t *err, int fd, off_t offset, int whence) {
5✔
1981
  const char *what = "lseek()", *explained = NULL;
5✔
1982
  int xerrno = ENOSYS;
5✔
1983

1984
  if (check_error(err) < 0) {
5✔
1985
    return -1;
1986
  }
1987

1988
  (void) pr_error_set_what(err, what);
3✔
1989

1990
  if (error_explainer->explainer->explain_lseek != NULL) {
3✔
1991
    explained = (error_explainer->explainer->explain_lseek)(err->err_pool,
2✔
1992
      err->err_errno, fd, offset, whence, &(err->err_args));
1993
    xerrno = errno;
2✔
1994
  }
1995

1996
  if (explained == NULL) {
2✔
1997
    trace_explained_error(what, xerrno);
2✔
1998
    errno = xerrno;
2✔
1999
    return -1;
2✔
2000
  }
2001

2002
  err->err_explained = explained;
1✔
2003
  return 0;
1✔
2004
}
2005

2006
int pr_error_explain_lstat(pr_error_t *err, const char *path,
7✔
2007
    struct stat *st) {
2008
  const char *what = "lstat()", *explained = NULL;
7✔
2009
  int xerrno = ENOSYS;
7✔
2010

2011
  if (check_error(err) < 0) {
7✔
2012
    return -1;
2013
  }
2014

2015
  (void) pr_error_set_what(err, what);
4✔
2016

2017
  if (error_explainer->explainer->explain_lstat != NULL) {
4✔
2018
    explained = (error_explainer->explainer->explain_lstat)(err->err_pool,
3✔
2019
      err->err_errno, path, st, &(err->err_args));
2020
    xerrno = errno;
3✔
2021
  }
2022

2023
  if (explained == NULL) {
3✔
2024
    trace_explained_error(what, xerrno);
2✔
2025
    errno = xerrno;
2✔
2026
    return -1;
2✔
2027
  }
2028

2029
  err->err_explained = explained;
2✔
2030
  return 0;
2✔
2031
}
2032

2033
int pr_error_explain_mkdir(pr_error_t *err, const char *path, mode_t mode) {
7✔
2034
  const char *what = "mkdir()", *explained = NULL;
7✔
2035
  int xerrno = ENOSYS;
7✔
2036

2037
  if (check_error(err) < 0) {
7✔
2038
    return -1;
2039
  }
2040

2041
  (void) pr_error_set_what(err, what);
4✔
2042

2043
  if (error_explainer->explainer->explain_mkdir != NULL) {
4✔
2044
    explained = (error_explainer->explainer->explain_mkdir)(err->err_pool,
3✔
2045
      err->err_errno, path, mode, &(err->err_args));
2046
    xerrno = errno;
3✔
2047
  }
2048

2049
  if (explained == NULL) {
3✔
2050
    trace_explained_error(what, xerrno);
2✔
2051
    errno = xerrno;
2✔
2052
    return -1;
2✔
2053
  }
2054

2055
  err->err_explained = explained;
2✔
2056
  return 0;
2✔
2057
}
2058

2059
int pr_error_explain_mkdtemp(pr_error_t *err, char *tmpl) {
5✔
2060
  const char *what = "mkdtemp()", *explained = NULL;
5✔
2061
  int xerrno = ENOSYS;
5✔
2062

2063
  if (check_error(err) < 0) {
5✔
2064
    return -1;
2065
  }
2066

2067
  (void) pr_error_set_what(err, what);
3✔
2068

2069
  if (error_explainer->explainer->explain_mkdtemp != NULL) {
3✔
2070
    explained = (error_explainer->explainer->explain_mkdtemp)(err->err_pool,
2✔
2071
      err->err_errno, tmpl, &(err->err_args));
2072
    xerrno = errno;
2✔
2073
  }
2074

2075
  if (explained == NULL) {
2✔
2076
    trace_explained_error(what, xerrno);
2✔
2077
    errno = xerrno;
2✔
2078
    return -1;
2✔
2079
  }
2080

2081
  err->err_explained = explained;
1✔
2082
  return 0;
1✔
2083
}
2084

2085
int pr_error_explain_mkstemp(pr_error_t *err, char *tmpl) {
5✔
2086
  const char *what = "mkstemp()", *explained = NULL;
5✔
2087
  int xerrno = ENOSYS;
5✔
2088

2089
  if (check_error(err) < 0) {
5✔
2090
    return -1;
2091
  }
2092

2093
  (void) pr_error_set_what(err, what);
3✔
2094

2095
  if (error_explainer->explainer->explain_mkstemp != NULL) {
3✔
2096
    explained = (error_explainer->explainer->explain_mkstemp)(err->err_pool,
2✔
2097
      err->err_errno, tmpl, &(err->err_args));
2098
    xerrno = errno;
2✔
2099
  }
2100

2101
  if (explained == NULL) {
2✔
2102
    trace_explained_error(what, xerrno);
2✔
2103
    errno = xerrno;
2✔
2104
    return -1;
2✔
2105
  }
2106

2107
  err->err_explained = explained;
1✔
2108
  return 0;
1✔
2109
}
2110

2111
int pr_error_explain_open(pr_error_t *err, const char *path, int flags,
8✔
2112
    mode_t mode) {
2113
  const char *what = "open()", *explained = NULL;
8✔
2114
  int xerrno = ENOSYS;
8✔
2115

2116
  if (check_error(err) < 0) {
8✔
2117
    return -1;
2118
  }
2119

2120
  (void) pr_error_set_what(err, what);
5✔
2121

2122
  if (error_explainer->explainer->explain_open != NULL) {
5✔
2123
    explained = (error_explainer->explainer->explain_open)(err->err_pool,
4✔
2124
      err->err_errno, path, flags, mode, &(err->err_args));
2125
    xerrno = errno;
4✔
2126
  }
2127

2128
  if (explained == NULL) {
4✔
2129
    trace_explained_error(what, xerrno);
2✔
2130
    errno = xerrno;
2✔
2131
    return -1;
2✔
2132
  }
2133

2134
  err->err_explained = explained;
3✔
2135
  return 0;
3✔
2136
}
2137

2138
int pr_error_explain_opendir(pr_error_t *err, const char *path) {
5✔
2139
  const char *what = "opendir()", *explained = NULL;
5✔
2140
  int xerrno = ENOSYS;
5✔
2141

2142
  if (check_error(err) < 0) {
5✔
2143
    return -1;
2144
  }
2145

2146
  (void) pr_error_set_what(err, what);
3✔
2147

2148
  if (error_explainer->explainer->explain_opendir != NULL) {
3✔
2149
    explained = (error_explainer->explainer->explain_opendir)(err->err_pool,
2✔
2150
      err->err_errno, path, &(err->err_args));
2151
    xerrno = errno;
2✔
2152
  }
2153

2154
  if (explained == NULL) {
2✔
2155
    trace_explained_error(what, xerrno);
2✔
2156
    errno = xerrno;
2✔
2157
    return -1;
2✔
2158
  }
2159

2160
  err->err_explained = explained;
1✔
2161
  return 0;
1✔
2162
}
2163

2164
int pr_error_explain_read(pr_error_t *err, int fd, void *buf, size_t sz) {
7✔
2165
  const char *what = "read()", *explained = NULL;
7✔
2166
  int xerrno = ENOSYS;
7✔
2167

2168
  if (check_error(err) < 0) {
7✔
2169
    return -1;
2170
  }
2171

2172
  (void) pr_error_set_what(err, what);
4✔
2173

2174
  if (error_explainer->explainer->explain_read != NULL) {
4✔
2175
    explained = (error_explainer->explainer->explain_read)(err->err_pool,
3✔
2176
      err->err_errno, fd, buf, sz, &(err->err_args));
2177
    xerrno = errno;
3✔
2178
  }
2179

2180
  if (explained == NULL) {
3✔
2181
    trace_explained_error(what, xerrno);
2✔
2182
    errno = xerrno;
2✔
2183
    return -1;
2✔
2184
  }
2185

2186
  err->err_explained = explained;
2✔
2187
  return 0;
2✔
2188
}
2189

2190
int pr_error_explain_readdir(pr_error_t *err, void *dirh) {
5✔
2191
  const char *what = "readdir()", *explained = NULL;
5✔
2192
  int xerrno = ENOSYS;
5✔
2193

2194
  if (check_error(err) < 0) {
5✔
2195
    return -1;
2196
  }
2197

2198
  (void) pr_error_set_what(err, what);
3✔
2199

2200
  if (error_explainer->explainer->explain_readdir != NULL) {
3✔
2201
    explained = (error_explainer->explainer->explain_readdir)(err->err_pool,
2✔
2202
      err->err_errno, dirh, &(err->err_args));
2203
    xerrno = errno;
2✔
2204
  }
2205

2206
  if (explained == NULL) {
2✔
2207
    trace_explained_error(what, xerrno);
2✔
2208
    errno = xerrno;
2✔
2209
    return -1;
2✔
2210
  }
2211

2212
  err->err_explained = explained;
1✔
2213
  return 0;
1✔
2214
}
2215

2216
int pr_error_explain_readlink(pr_error_t *err, const char *path, char *buf,
5✔
2217
    size_t sz) {
2218
  const char *what = "readlink()", *explained = NULL;
5✔
2219
  int xerrno = ENOSYS;
5✔
2220

2221
  if (check_error(err) < 0) {
5✔
2222
    return -1;
2223
  }
2224

2225
  (void) pr_error_set_what(err, what);
3✔
2226

2227
  if (error_explainer->explainer->explain_readlink != NULL) {
3✔
2228
    explained = (error_explainer->explainer->explain_readlink)(err->err_pool,
2✔
2229
      err->err_errno, path, buf, sz, &(err->err_args));
2230
    xerrno = errno;
2✔
2231
  }
2232

2233
  if (explained == NULL) {
2✔
2234
    trace_explained_error(what, xerrno);
2✔
2235
    errno = xerrno;
2✔
2236
    return -1;
2✔
2237
  }
2238

2239
  err->err_explained = explained;
1✔
2240
  return 0;
1✔
2241
}
2242

2243
int pr_error_explain_readv(pr_error_t *err, int fd, const struct iovec *iov,
5✔
2244
    int iov_len) {
2245
  const char *what = "readv()", *explained = NULL;
5✔
2246
  int xerrno = ENOSYS;
5✔
2247

2248
  if (check_error(err) < 0) {
5✔
2249
    return -1;
2250
  }
2251

2252
  (void) pr_error_set_what(err, what);
3✔
2253

2254
  if (error_explainer->explainer->explain_readv != NULL) {
3✔
2255
    explained = (error_explainer->explainer->explain_readv)(err->err_pool,
2✔
2256
      err->err_errno, fd, iov, iov_len, &(err->err_args));
2257
    xerrno = errno;
2✔
2258
  }
2259

2260
  if (explained == NULL) {
2✔
2261
    trace_explained_error(what, xerrno);
2✔
2262
    errno = xerrno;
2✔
2263
    return -1;
2✔
2264
  }
2265

2266
  err->err_explained = explained;
1✔
2267
  return 0;
1✔
2268
}
2269

2270
int pr_error_explain_rename(pr_error_t *err, const char *old_path,
7✔
2271
    const char *new_path) {
2272
  const char *what = "rename()", *explained = NULL;
7✔
2273
  int xerrno = ENOSYS;
7✔
2274

2275
  if (check_error(err) < 0) {
7✔
2276
    return -1;
2277
  }
2278

2279
  (void) pr_error_set_what(err, what);
4✔
2280

2281
  if (error_explainer->explainer->explain_rename != NULL) {
4✔
2282
    explained = (error_explainer->explainer->explain_rename)(err->err_pool,
3✔
2283
      err->err_errno, old_path, new_path, &(err->err_args));
2284
    xerrno = errno;
3✔
2285
  }
2286

2287
  if (explained == NULL) {
3✔
2288
    trace_explained_error(what, xerrno);
2✔
2289
    errno = xerrno;
2✔
2290
    return -1;
2✔
2291
  }
2292

2293
  err->err_explained = explained;
2✔
2294
  return 0;
2✔
2295
}
2296

2297
int pr_error_explain_rmdir(pr_error_t *err, const char *path) {
6✔
2298
  const char *what = "rmdir()", *explained = NULL;
6✔
2299
  int xerrno = ENOSYS;
6✔
2300

2301
  if (check_error(err) < 0) {
6✔
2302
    return -1;
2303
  }
2304

2305
  (void) pr_error_set_what(err, what);
4✔
2306

2307
  if (error_explainer->explainer->explain_rmdir != NULL) {
4✔
2308
    explained = (error_explainer->explainer->explain_rmdir)(err->err_pool,
3✔
2309
      err->err_errno, path, &(err->err_args));
2310
    xerrno = errno;
3✔
2311
  }
2312

2313
  if (explained == NULL) {
3✔
2314
    trace_explained_error(what, xerrno);
2✔
2315
    errno = xerrno;
2✔
2316
    return -1;
2✔
2317
  }
2318

2319
  err->err_explained = explained;
2✔
2320
  return 0;
2✔
2321
}
2322

2323
int pr_error_explain_setegid(pr_error_t *err, gid_t gid) {
5✔
2324
  const char *what = "setegid()", *explained = NULL;
5✔
2325
  int xerrno = ENOSYS;
5✔
2326

2327
  if (check_error(err) < 0) {
5✔
2328
    return -1;
2329
  }
2330

2331
  (void) pr_error_set_what(err, what);
3✔
2332

2333
  if (error_explainer->explainer->explain_setegid != NULL) {
3✔
2334
    explained = (error_explainer->explainer->explain_setegid)(err->err_pool,
2✔
2335
      err->err_errno, gid, &(err->err_args));
2336
    xerrno = errno;
2✔
2337
  }
2338

2339
  if (explained == NULL) {
2✔
2340
    trace_explained_error(what, xerrno);
2✔
2341
    errno = xerrno;
2✔
2342
    return -1;
2✔
2343
  }
2344

2345
  err->err_explained = explained;
1✔
2346
  return 0;
1✔
2347
}
2348

2349
int pr_error_explain_seteuid(pr_error_t *err, uid_t uid) {
5✔
2350
  const char *what = "seteuid()", *explained = NULL;
5✔
2351
  int xerrno = ENOSYS;
5✔
2352

2353
  if (check_error(err) < 0) {
5✔
2354
    return -1;
2355
  }
2356

2357
  (void) pr_error_set_what(err, what);
3✔
2358

2359
  if (error_explainer->explainer->explain_seteuid != NULL) {
3✔
2360
    explained = (error_explainer->explainer->explain_seteuid)(err->err_pool,
2✔
2361
      err->err_errno, uid, &(err->err_args));
2362
    xerrno = errno;
2✔
2363
  }
2364

2365
  if (explained == NULL) {
2✔
2366
    trace_explained_error(what, xerrno);
2✔
2367
    errno = xerrno;
2✔
2368
    return -1;
2✔
2369
  }
2370

2371
  err->err_explained = explained;
1✔
2372
  return 0;
1✔
2373
}
2374

2375
int pr_error_explain_setgid(pr_error_t *err, gid_t gid) {
5✔
2376
  const char *what = "setgid()", *explained = NULL;
5✔
2377
  int xerrno = ENOSYS;
5✔
2378

2379
  if (check_error(err) < 0) {
5✔
2380
    return -1;
2381
  }
2382

2383
  (void) pr_error_set_what(err, what);
3✔
2384

2385
  if (error_explainer->explainer->explain_setgid != NULL) {
3✔
2386
    explained = (error_explainer->explainer->explain_setgid)(err->err_pool,
2✔
2387
      err->err_errno, gid, &(err->err_args));
2388
    xerrno = errno;
2✔
2389
  }
2390

2391
  if (explained == NULL) {
2✔
2392
    trace_explained_error(what, xerrno);
2✔
2393
    errno = xerrno;
2✔
2394
    return -1;
2✔
2395
  }
2396

2397
  err->err_explained = explained;
1✔
2398
  return 0;
1✔
2399
}
2400

2401
int pr_error_explain_setregid(pr_error_t *err, gid_t rgid, gid_t egid) {
5✔
2402
  const char *what = "setregid()", *explained = NULL;
5✔
2403
  int xerrno = ENOSYS;
5✔
2404

2405
  if (check_error(err) < 0) {
5✔
2406
    return -1;
2407
  }
2408

2409
  (void) pr_error_set_what(err, what);
3✔
2410

2411
  if (error_explainer->explainer->explain_setregid != NULL) {
3✔
2412
    explained = (error_explainer->explainer->explain_setregid)(err->err_pool,
2✔
2413
      err->err_errno, rgid, egid, &(err->err_args));
2414
    xerrno = errno;
2✔
2415
  }
2416

2417
  if (explained == NULL) {
2✔
2418
    trace_explained_error(what, xerrno);
2✔
2419
    errno = xerrno;
2✔
2420
    return -1;
2✔
2421
  }
2422

2423
  err->err_explained = explained;
1✔
2424
  return 0;
1✔
2425
}
2426

2427
int pr_error_explain_setresgid(pr_error_t *err, gid_t rgid, gid_t egid,
5✔
2428
    gid_t sgid) {
2429
  const char *what = "setresgid()", *explained = NULL;
5✔
2430
  int xerrno = ENOSYS;
5✔
2431

2432
  if (check_error(err) < 0) {
5✔
2433
    return -1;
2434
  }
2435

2436
  (void) pr_error_set_what(err, what);
3✔
2437

2438
  if (error_explainer->explainer->explain_setresgid != NULL) {
3✔
2439
    explained = (error_explainer->explainer->explain_setresgid)(
2✔
2440
      err->err_pool, err->err_errno, rgid, egid, sgid, &(err->err_args));
2441
    xerrno = errno;
2✔
2442
  }
2443

2444
  if (explained == NULL) {
2✔
2445
    trace_explained_error(what, xerrno);
2✔
2446
    errno = xerrno;
2✔
2447
    return -1;
2✔
2448
  }
2449

2450
  err->err_explained = explained;
1✔
2451
  return 0;
1✔
2452
}
2453

2454
int pr_error_explain_setresuid(pr_error_t *err, uid_t ruid, uid_t euid,
5✔
2455
    uid_t suid) {
2456
  const char *what = "setresuid()", *explained = NULL;
5✔
2457
  int xerrno = ENOSYS;
5✔
2458

2459
  if (check_error(err) < 0) {
5✔
2460
    return -1;
2461
  }
2462

2463
  (void) pr_error_set_what(err, what);
3✔
2464

2465
  if (error_explainer->explainer->explain_setresuid != NULL) {
3✔
2466
    explained = (error_explainer->explainer->explain_setresuid)(
2✔
2467
      err->err_pool, err->err_errno, ruid, euid, suid, &(err->err_args));
2468
    xerrno = errno;
2✔
2469
  }
2470

2471
  if (explained == NULL) {
2✔
2472
    trace_explained_error(what, xerrno);
2✔
2473
    errno = xerrno;
2✔
2474
    return -1;
2✔
2475
  }
2476

2477
  err->err_explained = explained;
1✔
2478
  return 0;
1✔
2479
}
2480

2481
int pr_error_explain_setreuid(pr_error_t *err, uid_t ruid, uid_t euid) {
5✔
2482
  const char *what = "setreuid()", *explained = NULL;
5✔
2483
  int xerrno = ENOSYS;
5✔
2484

2485
  if (check_error(err) < 0) {
5✔
2486
    return -1;
2487
  }
2488

2489
  (void) pr_error_set_what(err, what);
3✔
2490

2491
  if (error_explainer->explainer->explain_setreuid != NULL) {
3✔
2492
    explained = (error_explainer->explainer->explain_setreuid)(err->err_pool,
2✔
2493
      err->err_errno, ruid, euid, &(err->err_args));
2494
    xerrno = errno;
2✔
2495
  }
2496

2497
  if (explained == NULL) {
2✔
2498
    trace_explained_error(what, xerrno);
2✔
2499
    errno = xerrno;
2✔
2500
    return -1;
2✔
2501
  }
2502

2503
  err->err_explained = explained;
1✔
2504
  return 0;
1✔
2505
}
2506

2507
int pr_error_explain_setrlimit(pr_error_t *err, int resource,
5✔
2508
    const struct rlimit *rlim) {
2509
  const char *what = "setrlimit()", *explained = NULL;
5✔
2510
  int xerrno = ENOSYS;
5✔
2511

2512
  if (check_error(err) < 0) {
5✔
2513
    return -1;
2514
  }
2515

2516
  (void) pr_error_set_what(err, what);
3✔
2517

2518
  if (error_explainer->explainer->explain_setrlimit != NULL) {
3✔
2519
    explained = (error_explainer->explainer->explain_setrlimit)(
2✔
2520
      err->err_pool, err->err_errno, resource, rlim, &(err->err_args));
2521
    xerrno = errno;
2✔
2522
  }
2523

2524
  if (explained == NULL) {
2✔
2525
    trace_explained_error(what, xerrno);
2✔
2526
    errno = xerrno;
2✔
2527
    return -1;
2✔
2528
  }
2529

2530
  err->err_explained = explained;
1✔
2531
  return 0;
1✔
2532
}
2533

2534
int pr_error_explain_setsockopt(pr_error_t *err, int fd, int level, int option,
5✔
2535
    const void *val, socklen_t valsz) {
2536
  const char *what = "setsockopt()", *explained = NULL;
5✔
2537
  int xerrno = ENOSYS;
5✔
2538

2539
  if (check_error(err) < 0) {
5✔
2540
    return -1;
2541
  }
2542

2543
  (void) pr_error_set_what(err, what);
3✔
2544

2545
  if (error_explainer->explainer->explain_setsockopt != NULL) {
3✔
2546
    explained = (error_explainer->explainer->explain_setsockopt)(
2✔
2547
      err->err_pool, err->err_errno, fd, level, option, val, valsz,
2548
      &(err->err_args));
2549
    xerrno = errno;
2✔
2550
  }
2551

2552
  if (explained == NULL) {
2✔
2553
    trace_explained_error(what, xerrno);
2✔
2554
    errno = xerrno;
2✔
2555
    return -1;
2✔
2556
  }
2557

2558
  err->err_explained = explained;
1✔
2559
  return 0;
1✔
2560
}
2561

2562
int pr_error_explain_setuid(pr_error_t *err, uid_t uid) {
5✔
2563
  const char *what = "setuid()", *explained = NULL;
5✔
2564
  int xerrno = ENOSYS;
5✔
2565

2566
  if (check_error(err) < 0) {
5✔
2567
    return -1;
2568
  }
2569

2570
  (void) pr_error_set_what(err, what);
3✔
2571

2572
  if (error_explainer->explainer->explain_setuid != NULL) {
3✔
2573
    explained = (error_explainer->explainer->explain_setuid)(err->err_pool,
2✔
2574
      err->err_errno, uid, &(err->err_args));
2575
    xerrno = errno;
2✔
2576
  }
2577

2578
  if (explained == NULL) {
2✔
2579
    trace_explained_error(what, xerrno);
2✔
2580
    errno = xerrno;
2✔
2581
    return -1;
2✔
2582
  }
2583

2584
  err->err_explained = explained;
1✔
2585
  return 0;
1✔
2586
}
2587

2588
int pr_error_explain_socket(pr_error_t *err, int domain, int type, int proto) {
5✔
2589
  const char *what = "socket()", *explained = NULL;
5✔
2590
  int xerrno = ENOSYS;
5✔
2591

2592
  if (check_error(err) < 0) {
5✔
2593
    return -1;
2594
  }
2595

2596
  (void) pr_error_set_what(err, what);
3✔
2597

2598
  if (error_explainer->explainer->explain_socket != NULL) {
3✔
2599
    explained = (error_explainer->explainer->explain_socket)(err->err_pool,
2✔
2600
      err->err_errno, domain, type, proto, &(err->err_args));
2601
    xerrno = errno;
2✔
2602
  }
2603

2604
  if (explained == NULL) {
2✔
2605
    trace_explained_error(what, xerrno);
2✔
2606
    errno = xerrno;
2✔
2607
    return -1;
2✔
2608
  }
2609

2610
  err->err_explained = explained;
1✔
2611
  return 0;
1✔
2612
}
2613

2614
int pr_error_explain_stat(pr_error_t *err, const char *path, struct stat *st) {
7✔
2615
  const char *what = "stat()", *explained = NULL;
7✔
2616
  int xerrno = ENOSYS;
7✔
2617

2618
  if (check_error(err) < 0) {
7✔
2619
    return -1;
2620
  }
2621

2622
  (void) pr_error_set_what(err, what);
4✔
2623

2624
  if (error_explainer->explainer->explain_stat != NULL) {
4✔
2625
    explained = (error_explainer->explainer->explain_stat)(err->err_pool,
3✔
2626
      err->err_errno, path, st, &(err->err_args));
2627
    xerrno = errno;
3✔
2628
  }
2629

2630
  if (explained == NULL) {
3✔
2631
    trace_explained_error(what, xerrno);
2✔
2632
    errno = xerrno;
2✔
2633
    return -1;
2✔
2634
  }
2635

2636
  err->err_explained = explained;
2✔
2637
  return 0;
2✔
2638
}
2639

2640
int pr_error_explain_statfs(pr_error_t *err, const char *path, void *stfs) {
5✔
2641
  const char *what = "statfs()", *explained = NULL;
5✔
2642
  int xerrno = ENOSYS;
5✔
2643

2644
  if (check_error(err) < 0) {
5✔
2645
    return -1;
2646
  }
2647

2648
  (void) pr_error_set_what(err, what);
3✔
2649

2650
  if (error_explainer->explainer->explain_statfs != NULL) {
3✔
2651
    explained = (error_explainer->explainer->explain_statfs)(err->err_pool,
2✔
2652
      err->err_errno, path, stfs, &(err->err_args));
2653
    xerrno = errno;
2✔
2654
  }
2655

2656
  if (explained == NULL) {
2✔
2657
    trace_explained_error(what, xerrno);
2✔
2658
    errno = xerrno;
2✔
2659
    return -1;
2✔
2660
  }
2661

2662
  err->err_explained = explained;
1✔
2663
  return 0;
1✔
2664
}
2665

2666
int pr_error_explain_statvfs(pr_error_t *err, const char *path, void *stfs) {
5✔
2667
  const char *what = "statvfs()", *explained = NULL;
5✔
2668
  int xerrno = ENOSYS;
5✔
2669

2670
  if (check_error(err) < 0) {
5✔
2671
    return -1;
2672
  }
2673

2674
  (void) pr_error_set_what(err, what);
3✔
2675

2676
  if (error_explainer->explainer->explain_statvfs != NULL) {
3✔
2677
    explained = (error_explainer->explainer->explain_statvfs)(err->err_pool,
2✔
2678
      err->err_errno, path, stfs, &(err->err_args));
2679
    xerrno = errno;
2✔
2680
  }
2681

2682
  if (explained == NULL) {
2✔
2683
    trace_explained_error(what, xerrno);
2✔
2684
    errno = xerrno;
2✔
2685
    return -1;
2✔
2686
  }
2687

2688
  err->err_explained = explained;
1✔
2689
  return 0;
1✔
2690
}
2691

2692
int pr_error_explain_symlink(pr_error_t *err, const char *target_path,
5✔
2693
    const char *link_path) {
2694
  const char *what = "symlink()", *explained = NULL;
5✔
2695
  int xerrno = ENOSYS;
5✔
2696

2697
  if (check_error(err) < 0) {
5✔
2698
    return -1;
2699
  }
2700

2701
  (void) pr_error_set_what(err, what);
3✔
2702

2703
  if (error_explainer->explainer->explain_symlink != NULL) {
3✔
2704
    explained = (error_explainer->explainer->explain_symlink)(err->err_pool,
2✔
2705
      err->err_errno, target_path, link_path, &(err->err_args));
2706
    xerrno = errno;
2✔
2707
  }
2708

2709
  if (explained == NULL) {
2✔
2710
    trace_explained_error(what, xerrno);
2✔
2711
    errno = xerrno;
2✔
2712
    return -1;
2✔
2713
  }
2714

2715
  err->err_explained = explained;
1✔
2716
  return 0;
1✔
2717
}
2718

2719
int pr_error_explain_truncate(pr_error_t *err, const char *path, off_t len) {
5✔
2720
  const char *what = "truncate()", *explained = NULL;
5✔
2721
  int xerrno = ENOSYS;
5✔
2722

2723
  if (check_error(err) < 0) {
5✔
2724
    return -1;
2725
  }
2726

2727
  (void) pr_error_set_what(err, what);
3✔
2728

2729
  if (error_explainer->explainer->explain_truncate != NULL) {
3✔
2730
    explained = (error_explainer->explainer->explain_truncate)(err->err_pool,
2✔
2731
      err->err_errno, path, len, &(err->err_args));
2732
    xerrno = errno;
2✔
2733
  }
2734

2735
  if (explained == NULL) {
2✔
2736
    trace_explained_error(what, xerrno);
2✔
2737
    errno = xerrno;
2✔
2738
    return -1;
2✔
2739
  }
2740

2741
  err->err_explained = explained;
1✔
2742
  return 0;
1✔
2743
}
2744

2745
int pr_error_explain_unlink(pr_error_t *err, const char *path) {
7✔
2746
  const char *what = "unlink()", *explained = NULL;
7✔
2747
  int xerrno = ENOSYS;
7✔
2748

2749
  if (check_error(err) < 0) {
7✔
2750
    return -1;
2751
  }
2752

2753
  (void) pr_error_set_what(err, what);
4✔
2754

2755
  if (error_explainer->explainer->explain_unlink != NULL) {
4✔
2756
    explained = (error_explainer->explainer->explain_unlink)(err->err_pool,
3✔
2757
      err->err_errno, path, &(err->err_args));
2758
    xerrno = errno;
3✔
2759
  }
2760

2761
  if (explained == NULL) {
3✔
2762
    trace_explained_error(what, xerrno);
2✔
2763
    errno = xerrno;
2✔
2764
    return -1;
2✔
2765
  }
2766

2767
  err->err_explained = explained;
2✔
2768
  return 0;
2✔
2769
}
2770

2771
int pr_error_explain_utimes(pr_error_t *err, const char *path,
5✔
2772
    const struct timeval *tvs) {
2773
  const char *what = "utimes()", *explained = NULL;
5✔
2774
  int xerrno = ENOSYS;
5✔
2775

2776
  if (check_error(err) < 0) {
5✔
2777
    return -1;
2778
  }
2779

2780
  (void) pr_error_set_what(err, what);
3✔
2781

2782
  if (error_explainer->explainer->explain_utimes != NULL) {
3✔
2783
    explained = (error_explainer->explainer->explain_utimes)(err->err_pool,
2✔
2784
      err->err_errno, path, tvs, &(err->err_args));
2785
    xerrno = errno;
2✔
2786
  }
2787

2788
  if (explained == NULL) {
2✔
2789
    trace_explained_error(what, xerrno);
2✔
2790
    errno = xerrno;
2✔
2791
    return -1;
2✔
2792
  }
2793

2794
  err->err_explained = explained;
1✔
2795
  return 0;
1✔
2796
}
2797

2798
int pr_error_explain_write(pr_error_t *err, int fd, const void *buf,
7✔
2799
    size_t sz) {
2800
  const char *what = "write()", *explained = NULL;
7✔
2801
  int xerrno = ENOSYS;
7✔
2802

2803
  if (check_error(err) < 0) {
7✔
2804
    return -1;
2805
  }
2806

2807
  (void) pr_error_set_what(err, what);
4✔
2808

2809
  if (error_explainer->explainer->explain_write != NULL) {
4✔
2810
    explained = (error_explainer->explainer->explain_write)(err->err_pool,
3✔
2811
      err->err_errno, fd, buf, sz, &(err->err_args));
2812
    xerrno = errno;
3✔
2813
  }
2814

2815
  if (explained == NULL) {
3✔
2816
    trace_explained_error(what, xerrno);
2✔
2817
    errno = xerrno;
2✔
2818
    return -1;
2✔
2819
  }
2820

2821
  err->err_explained = explained;
2✔
2822
  return 0;
2✔
2823
}
2824

2825
int pr_error_explain_writev(pr_error_t *err, int fd,
5✔
2826
    const struct iovec *iov, int iov_len) {
2827
  const char *what = "writev()", *explained = NULL;
5✔
2828
  int xerrno = ENOSYS;
5✔
2829

2830
  if (check_error(err) < 0) {
5✔
2831
    return -1;
2832
  }
2833

2834
  (void) pr_error_set_what(err, what);
3✔
2835

2836
  if (error_explainer->explainer->explain_writev != NULL) {
3✔
2837
    explained = (error_explainer->explainer->explain_writev)(err->err_pool,
2✔
2838
      err->err_errno, fd, iov, iov_len, &(err->err_args));
2839
    xerrno = errno;
2✔
2840
  }
2841

2842
  if (explained == NULL) {
2✔
2843
    trace_explained_error(what, xerrno);
2✔
2844
    errno = xerrno;
2✔
2845
    return -1;
2✔
2846
  }
2847

2848
  err->err_explained = explained;
1✔
2849
  return 0;
1✔
2850
}
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