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

proftpd / proftpd / 28042938174

23 Jun 2026 05:02PM UTC coverage: 92.464% (-0.6%) from 93.027%
28042938174

push

github

web-flow
It is possible for a client to say that it wishes to use the "sk-ssh-ed25519@openssh.com" algorithm for SSH user publickey authentication, but to _actually_ provide an "ssh-ed25519" public key.

The issue is that, when verifying the type of the public key provided by the client, we do not enforce that the provided key algorith matches the expected public key algorithm.

Thanks to Fabian Wahle of Hap Security for reporting this issue.

48661 of 52627 relevant lines covered (92.46%)

234.31 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