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

proftpd / proftpd / 14136377169

28 Mar 2025 07:21PM UTC coverage: 92.663% (-0.4%) from 93.027%
14136377169

push

github

Castaglia
To aid in debugging of unexpectedly malfunctioning authorized SSH keys, add trace logging of any lines of text which are not formatted as expected.

47143 of 50876 relevant lines covered (92.66%)

237.38 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