The FreeRADIUS server $Id: f3670dba8951ca10eb4948feb3dc3db9423a334f $
Loading...
Searching...
No Matches
fd_write.h
Go to the documentation of this file.
1#pragma once
2/*
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
16 */
17
18/**
19 * $Id: 8560f46f6f0b022f601297bb4e85a5d126703a0e $
20 * @file lib/bio/fd_write.h
21 * @brief Common finalization code for the FD bio write functions.
22 *
23 * @copyright 2024 Network RADIUS SAS (legal@networkradius.com)
24 */
25RCSIDH(lib_bio_fd_write_h, "$Id: 8560f46f6f0b022f601297bb4e85a5d126703a0e $")
26
27#include <freeradius-devel/bio/fd_errno.h>
28
29/** Common finalization code for the write functions.
30 *
31 * @todo - do we want the callbacks to notify the _previous_ BIO in the chain? That way the top-level
32 * BIO can notify the application.
33 *
34 * @param my the FD bio.
35 * @param[in,out] rcode_p in: the write() return code. out: what to return to the application.
36 * @param[in,out] tries_p how many times we have retried on EINTR.
37 * @param size how many bytes the application asked us to write.
38 * @return
39 * - false return *rcode_p to the application.
40 * - true the write was interrupted, redo it.
41 */
42static inline CC_HINT(always_inline) bool fr_bio_fd_write_retry(fr_bio_fd_t *my, ssize_t *rcode_p, int *tries_p, size_t size)
43{
44 ssize_t rcode = *rcode_p;
45
46 if (rcode > 0) {
47 int error;
48
49 /*
50 * We weren't blocked, but we may be blocked now.
51 */
52 if (!my->info.write_blocked) {
53 if ((size_t) rcode == size) return false;
54
55 fr_assert((size_t) rcode < size);
56
57 /*
58 * Set the flag, and tell the other BIOs that we're blocked.
59 */
60 my->info.write_blocked = true;
61
62 error = fr_bio_write_blocked((fr_bio_t *) my);
63 if (error < 0) *rcode_p = error;
64
65 return false;
66 }
67
68 /*
69 * We were blocked. We're still blocked if we wrote _less_ than the amount of requested data.
70 * If we wrote all of the data which was requested, then we're unblocked.
71 */
72 my->info.write_blocked = ((size_t) rcode < size);
73
74 /*
75 * Call the "resume" function if we transitioned to being unblocked.
76 */
77 if (!my->info.write_blocked && my->cb.write_resume) {
78 error = my->cb.write_resume((fr_bio_t *) my);
79 if (error < 0) *rcode_p = error;
80 }
81
82 return false;
83 }
84
85 if (rcode == 0) return false;
86
87 return fr_bio_fd_errno_retry(my, rcode_p, tries_p, true);
88}
#define RCSIDH(h, id)
Definition build.h:561
bool write_blocked
did we block on write?
Definition fd.h:135
static bool fr_bio_fd_errno_retry(fr_bio_fd_t *my, ssize_t *rcode_p, int *tries_p, bool is_write)
Turn a failed read / write into a bio return code.
Definition fd_errno.h:41
fr_bio_fd_info_t info
Definition fd_priv.h:39
Our FD bio structure.
Definition fd_priv.h:35
static bool fr_bio_fd_write_retry(fr_bio_fd_t *my, ssize_t *rcode_p, int *tries_p, size_t size)
Common finalization code for the write functions.
Definition fd_write.h:42
int fr_bio_write_blocked(fr_bio_t *bio)
Internal BIO function to tell all BIOs that it's blocked.
Definition base.c:272
long int ssize_t
unsigned long int size_t
#define fr_assert(_expr)
Definition rad_assert.h:37