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

proftpd / proftpd / 14581522647

21 Apr 2025 09:13PM UTC coverage: 92.667% (-0.4%) from 93.03%
14581522647

push

github

Castaglia
Adding a regression test for Bug#4417.

47172 of 50905 relevant lines covered (92.67%)

250.83 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-2020 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, write to the Free Software
17
 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
18
 *
19
 * As a special exemption, The ProFTPD Project team and other respective
20
 * copyright holders give permission to link this program with OpenSSL, and
21
 * distribute the resulting executable, without including the source code for
22
 * OpenSSL in the source distribution.
23
 */
24

25
/* Error API */
26

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

34
#define PR_ERROR_BUFSZ                32
35

36
struct err_rec {
37
  pool *err_pool;
38

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

322
  { -1, NULL }
323
};
324

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

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

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

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

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

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

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

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

354
  return err;
119✔
355
}
356

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

360
  xerrno = errno;
120✔
361

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

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

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

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

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

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

389
  return 0;
390
}
391

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

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

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

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

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

415
  return 0;
5✔
416
}
417

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

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

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

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

435
  return prev;
8✔
436
}
437

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

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

444
  return prev;
6✔
445
}
446

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

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

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

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

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

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

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

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

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

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

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

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

508
      proto = pr_session_get_protocol(0);
5✔
509

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

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

519
  return who;
12✔
520
}
521

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

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

529
  return why;
530
}
531

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

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

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

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

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

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

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

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

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

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

577
  return where;
12✔
578
}
579

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

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

587
  return what;
588
}
589

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

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

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

603
  return what;
12✔
604
}
605

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

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

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

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

627
  return name;
628
}
629

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

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

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

641
  return desc;
642
}
643

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

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

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

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

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

666
  return failure;
36✔
667
}
668

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

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

676
  return explained;
677
}
678

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

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

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

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

696
  return err_text;
22✔
697
}
698

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

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

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

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

725
  return err_text;
2✔
726
}
727

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

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

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

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

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

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

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

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

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

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

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

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

792
  return err_text;
12✔
793
}
794

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

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

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

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

811
      } else {
812
        break;
813
      }
814

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

819
      } else {
820
        break;
821
      }
822

823
    case PR_ERROR_FORMAT_USE_MINIMAL:
824
      break;
825

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

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

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

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

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

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

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

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

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

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

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

879
  return err_text;
880
}
881

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

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

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

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

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

914
  } else {
915
    error_explainers = ee;
89✔
916
  }
917

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

925
  return explainer;
926
}
927

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

932
  (void) p;
933

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

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

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

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

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

959
      ee->prev = ee->next = NULL;
89✔
960

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

968
      res = 0;
969
    }
970
  }
971

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

976
  return res;
977
}
978

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

982
  (void) p;
983

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

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

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

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

1009
  errno = ENOENT;
1✔
1010
  return -1;
1✔
1011
}
1012

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

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

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

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

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

1046
  return 0;
1047
}
1048

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

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

1058
  (void) pr_error_set_why(err, what);
3✔
1059

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

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

1072
  err->err_explained = explained;
1✔
1073
  return 0;
1✔
1074
}
1075

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

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

1085
  (void) pr_error_set_what(err, what);
3✔
1086

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

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

1099
  err->err_explained = explained;
1✔
1100
  return 0;
1✔
1101
}
1102

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

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

1111
  (void) pr_error_set_what(err, what);
3✔
1112

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

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

1125
  err->err_explained = explained;
1✔
1126
  return 0;
1✔
1127
}
1128

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

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

1137
  (void) pr_error_set_what(err, what);
4✔
1138

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

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

1151
  err->err_explained = explained;
2✔
1152
  return 0;
2✔
1153
}
1154

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

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

1164
  (void) pr_error_set_what(err, what);
4✔
1165

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

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

1178
  err->err_explained = explained;
2✔
1179
  return 0;
2✔
1180
}
1181

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

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

1190
  (void) pr_error_set_what(err, what);
4✔
1191

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

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

1204
  err->err_explained = explained;
2✔
1205
  return 0;
2✔
1206
}
1207

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

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

1216
  (void) pr_error_set_what(err, what);
4✔
1217

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

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

1230
  err->err_explained = explained;
2✔
1231
  return 0;
2✔
1232
}
1233

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

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

1242
  (void) pr_error_set_what(err, what);
3✔
1243

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

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

1256
  err->err_explained = explained;
1✔
1257
  return 0;
1✔
1258
}
1259

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

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

1269
  (void) pr_error_set_what(err, what);
3✔
1270

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

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

1283
  err->err_explained = explained;
1✔
1284
  return 0;
1✔
1285
}
1286

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

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

1295
  (void) pr_error_set_what(err, what);
4✔
1296

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

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

1309
  err->err_explained = explained;
2✔
1310
  return 0;
2✔
1311
}
1312

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

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

1321
  (void) pr_error_set_what(err, what);
4✔
1322

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

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

1335
  err->err_explained = explained;
2✔
1336
  return 0;
2✔
1337
}
1338

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

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

1347
  (void) pr_error_set_what(err, what);
3✔
1348

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

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

1361
  err->err_explained = explained;
1✔
1362
  return 0;
1✔
1363
}
1364

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

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

1373
  (void) pr_error_set_what(err, what);
3✔
1374

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

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

1387
  err->err_explained = explained;
1✔
1388
  return 0;
1✔
1389
}
1390

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

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

1399
  (void) pr_error_set_what(err, what);
3✔
1400

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

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

1413
  err->err_explained = explained;
1✔
1414
  return 0;
1✔
1415
}
1416

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

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

1425
  (void) pr_error_set_what(err, what);
3✔
1426

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

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

1439
  err->err_explained = explained;
1✔
1440
  return 0;
1✔
1441
}
1442

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

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

1452
  (void) pr_error_set_what(err, what);
3✔
1453

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

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

1466
  err->err_explained = explained;
1✔
1467
  return 0;
1✔
1468
}
1469

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

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

1478
  (void) pr_error_set_what(err, what);
3✔
1479

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

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

1492
  err->err_explained = explained;
1✔
1493
  return 0;
1✔
1494
}
1495

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

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

1504
  (void) pr_error_set_what(err, what);
3✔
1505

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

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

1518
  err->err_explained = explained;
1✔
1519
  return 0;
1✔
1520
}
1521

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

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

1530
  (void) pr_error_set_what(err, what);
3✔
1531

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

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

1544
  err->err_explained = explained;
1✔
1545
  return 0;
1✔
1546
}
1547

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

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

1556
  (void) pr_error_set_what(err, what);
3✔
1557

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

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

1570
  err->err_explained = explained;
1✔
1571
  return 0;
1✔
1572
}
1573

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

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

1582
  (void) pr_error_set_what(err, what);
3✔
1583

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

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

1596
  err->err_explained = explained;
1✔
1597
  return 0;
1✔
1598
}
1599

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

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

1608
  (void) pr_error_set_what(err, what);
3✔
1609

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

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

1622
  err->err_explained = explained;
1✔
1623
  return 0;
1✔
1624
}
1625

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

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

1635
  (void) pr_error_set_what(err, what);
3✔
1636

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

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

1649
  err->err_explained = explained;
1✔
1650
  return 0;
1✔
1651
}
1652

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

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

1662
  (void) pr_error_set_what(err, what);
3✔
1663

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

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

1677
  err->err_explained = explained;
1✔
1678
  return 0;
1✔
1679
}
1680

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

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

1689
  (void) pr_error_set_what(err, what);
3✔
1690

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

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

1703
  err->err_explained = explained;
1✔
1704
  return 0;
1✔
1705
}
1706

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

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

1716
  (void) pr_error_set_what(err, what);
3✔
1717

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

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

1730
  err->err_explained = explained;
1✔
1731
  return 0;
1✔
1732
}
1733

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

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

1742
  (void) pr_error_set_what(err, what);
3✔
1743

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

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

1756
  err->err_explained = explained;
1✔
1757
  return 0;
1✔
1758
}
1759

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

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

1770
  (void) pr_error_set_what(err, what);
3✔
1771

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

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

1785
  err->err_explained = explained;
1✔
1786
  return 0;
1✔
1787
}
1788

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

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

1798
  (void) pr_error_set_what(err, what);
3✔
1799

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

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

1812
  err->err_explained = explained;
1✔
1813
  return 0;
1✔
1814
}
1815

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

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

1825
  (void) pr_error_set_what(err, what);
3✔
1826

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

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

1839
  err->err_explained = explained;
1✔
1840
  return 0;
1✔
1841
}
1842

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

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

1852
  (void) pr_error_set_what(err, what);
3✔
1853

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

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

1866
  err->err_explained = explained;
1✔
1867
  return 0;
1✔
1868
}
1869

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

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

1879
  (void) pr_error_set_what(err, what);
3✔
1880

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

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

1894
  err->err_explained = explained;
1✔
1895
  return 0;
1✔
1896
}
1897

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

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

1907
  (void) pr_error_set_what(err, what);
4✔
1908

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

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

1921
  err->err_explained = explained;
2✔
1922
  return 0;
2✔
1923
}
1924

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

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

1934
  (void) pr_error_set_what(err, what);
3✔
1935

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

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

1948
  err->err_explained = explained;
1✔
1949
  return 0;
1✔
1950
}
1951

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

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

1960
  (void) pr_error_set_what(err, what);
3✔
1961

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

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

1974
  err->err_explained = explained;
1✔
1975
  return 0;
1✔
1976
}
1977

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

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

1986
  (void) pr_error_set_what(err, what);
3✔
1987

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

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

2000
  err->err_explained = explained;
1✔
2001
  return 0;
1✔
2002
}
2003

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

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

2013
  (void) pr_error_set_what(err, what);
4✔
2014

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

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

2027
  err->err_explained = explained;
2✔
2028
  return 0;
2✔
2029
}
2030

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

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

2039
  (void) pr_error_set_what(err, what);
4✔
2040

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

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

2053
  err->err_explained = explained;
2✔
2054
  return 0;
2✔
2055
}
2056

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

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

2065
  (void) pr_error_set_what(err, what);
3✔
2066

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

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

2079
  err->err_explained = explained;
1✔
2080
  return 0;
1✔
2081
}
2082

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

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

2091
  (void) pr_error_set_what(err, what);
3✔
2092

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

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

2105
  err->err_explained = explained;
1✔
2106
  return 0;
1✔
2107
}
2108

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

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

2118
  (void) pr_error_set_what(err, what);
5✔
2119

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

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

2132
  err->err_explained = explained;
3✔
2133
  return 0;
3✔
2134
}
2135

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

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

2144
  (void) pr_error_set_what(err, what);
3✔
2145

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

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

2158
  err->err_explained = explained;
1✔
2159
  return 0;
1✔
2160
}
2161

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

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

2170
  (void) pr_error_set_what(err, what);
4✔
2171

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

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

2184
  err->err_explained = explained;
2✔
2185
  return 0;
2✔
2186
}
2187

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

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

2196
  (void) pr_error_set_what(err, what);
3✔
2197

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

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

2210
  err->err_explained = explained;
1✔
2211
  return 0;
1✔
2212
}
2213

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

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

2223
  (void) pr_error_set_what(err, what);
3✔
2224

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

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

2237
  err->err_explained = explained;
1✔
2238
  return 0;
1✔
2239
}
2240

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

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

2250
  (void) pr_error_set_what(err, what);
3✔
2251

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

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

2264
  err->err_explained = explained;
1✔
2265
  return 0;
1✔
2266
}
2267

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

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

2277
  (void) pr_error_set_what(err, what);
4✔
2278

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

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

2291
  err->err_explained = explained;
2✔
2292
  return 0;
2✔
2293
}
2294

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

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

2303
  (void) pr_error_set_what(err, what);
4✔
2304

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

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

2317
  err->err_explained = explained;
2✔
2318
  return 0;
2✔
2319
}
2320

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

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

2329
  (void) pr_error_set_what(err, what);
3✔
2330

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

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

2343
  err->err_explained = explained;
1✔
2344
  return 0;
1✔
2345
}
2346

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

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

2355
  (void) pr_error_set_what(err, what);
3✔
2356

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

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

2369
  err->err_explained = explained;
1✔
2370
  return 0;
1✔
2371
}
2372

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

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

2381
  (void) pr_error_set_what(err, what);
3✔
2382

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

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

2395
  err->err_explained = explained;
1✔
2396
  return 0;
1✔
2397
}
2398

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

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

2407
  (void) pr_error_set_what(err, what);
3✔
2408

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

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

2421
  err->err_explained = explained;
1✔
2422
  return 0;
1✔
2423
}
2424

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

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

2434
  (void) pr_error_set_what(err, what);
3✔
2435

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

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

2448
  err->err_explained = explained;
1✔
2449
  return 0;
1✔
2450
}
2451

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

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

2461
  (void) pr_error_set_what(err, what);
3✔
2462

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

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

2475
  err->err_explained = explained;
1✔
2476
  return 0;
1✔
2477
}
2478

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

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

2487
  (void) pr_error_set_what(err, what);
3✔
2488

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

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

2501
  err->err_explained = explained;
1✔
2502
  return 0;
1✔
2503
}
2504

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

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

2514
  (void) pr_error_set_what(err, what);
3✔
2515

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

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

2528
  err->err_explained = explained;
1✔
2529
  return 0;
1✔
2530
}
2531

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

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

2541
  (void) pr_error_set_what(err, what);
3✔
2542

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

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

2556
  err->err_explained = explained;
1✔
2557
  return 0;
1✔
2558
}
2559

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

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

2568
  (void) pr_error_set_what(err, what);
3✔
2569

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

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

2582
  err->err_explained = explained;
1✔
2583
  return 0;
1✔
2584
}
2585

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

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

2594
  (void) pr_error_set_what(err, what);
3✔
2595

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

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

2608
  err->err_explained = explained;
1✔
2609
  return 0;
1✔
2610
}
2611

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

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

2620
  (void) pr_error_set_what(err, what);
4✔
2621

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

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

2634
  err->err_explained = explained;
2✔
2635
  return 0;
2✔
2636
}
2637

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

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

2646
  (void) pr_error_set_what(err, what);
3✔
2647

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

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

2660
  err->err_explained = explained;
1✔
2661
  return 0;
1✔
2662
}
2663

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

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

2672
  (void) pr_error_set_what(err, what);
3✔
2673

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

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

2686
  err->err_explained = explained;
1✔
2687
  return 0;
1✔
2688
}
2689

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

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

2699
  (void) pr_error_set_what(err, what);
3✔
2700

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

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

2713
  err->err_explained = explained;
1✔
2714
  return 0;
1✔
2715
}
2716

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

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

2725
  (void) pr_error_set_what(err, what);
3✔
2726

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

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

2739
  err->err_explained = explained;
1✔
2740
  return 0;
1✔
2741
}
2742

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

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

2751
  (void) pr_error_set_what(err, what);
4✔
2752

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

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

2765
  err->err_explained = explained;
2✔
2766
  return 0;
2✔
2767
}
2768

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

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

2778
  (void) pr_error_set_what(err, what);
3✔
2779

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

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

2792
  err->err_explained = explained;
1✔
2793
  return 0;
1✔
2794
}
2795

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

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

2805
  (void) pr_error_set_what(err, what);
4✔
2806

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

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

2819
  err->err_explained = explained;
2✔
2820
  return 0;
2✔
2821
}
2822

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

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

2832
  (void) pr_error_set_what(err, what);
3✔
2833

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

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

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