]> git.proxmox.com Git - mirror_frr.git/blob - lib/network.c
Merge pull request #13649 from donaldsharp/unlock_the_node_or_else
[mirror_frr.git] / lib / network.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Network library.
4 * Copyright (C) 1997 Kunihiro Ishiguro
5 */
6
7 #include <zebra.h>
8 #include "log.h"
9 #include "network.h"
10 #include "lib_errors.h"
11
12 /* Read nbytes from fd and store into ptr. */
13 int readn(int fd, uint8_t *ptr, int nbytes)
14 {
15 int nleft;
16 int nread;
17
18 nleft = nbytes;
19
20 while (nleft > 0) {
21 nread = read(fd, ptr, nleft);
22
23 if (nread < 0)
24 return (nread);
25 else if (nread == 0)
26 break;
27
28 nleft -= nread;
29 ptr += nread;
30 }
31
32 return nbytes - nleft;
33 }
34
35 /* Write nbytes from ptr to fd. */
36 int writen(int fd, const uint8_t *ptr, int nbytes)
37 {
38 int nleft;
39 int nwritten;
40
41 nleft = nbytes;
42
43 while (nleft > 0) {
44 nwritten = write(fd, ptr, nleft);
45
46 if (nwritten < 0) {
47 if (!ERRNO_IO_RETRY(errno))
48 return nwritten;
49 }
50 if (nwritten == 0)
51 return (nwritten);
52
53 nleft -= nwritten;
54 ptr += nwritten;
55 }
56 return nbytes - nleft;
57 }
58
59 int set_nonblocking(int fd)
60 {
61 int flags;
62
63 /* According to the Single UNIX Spec, the return value for F_GETFL
64 should
65 never be negative. */
66 flags = fcntl(fd, F_GETFL);
67 if (flags < 0) {
68 flog_err(EC_LIB_SYSTEM_CALL,
69 "fcntl(F_GETFL) failed for fd %d: %s", fd,
70 safe_strerror(errno));
71 return -1;
72 }
73 if (fcntl(fd, F_SETFL, (flags | O_NONBLOCK)) < 0) {
74 flog_err(EC_LIB_SYSTEM_CALL,
75 "fcntl failed setting fd %d non-blocking: %s", fd,
76 safe_strerror(errno));
77 return -1;
78 }
79 return 0;
80 }
81
82 int set_cloexec(int fd)
83 {
84 int flags;
85 flags = fcntl(fd, F_GETFD, 0);
86 if (flags == -1)
87 return -1;
88
89 flags |= FD_CLOEXEC;
90 if (fcntl(fd, F_SETFD, flags) == -1)
91 return -1;
92 return 0;
93 }
94
95 float htonf(float host)
96 {
97 uint32_t lu1, lu2;
98 float convert;
99
100 memcpy(&lu1, &host, sizeof(uint32_t));
101 lu2 = htonl(lu1);
102 memcpy(&convert, &lu2, sizeof(uint32_t));
103 return convert;
104 }
105
106 float ntohf(float net)
107 {
108 return htonf(net);
109 }
110
111 uint64_t frr_sequence_next(void)
112 {
113 static uint64_t last_sequence;
114 struct timespec ts;
115
116 (void)clock_gettime(CLOCK_MONOTONIC, &ts);
117 if (last_sequence == (uint64_t)ts.tv_sec) {
118 last_sequence++;
119 return last_sequence;
120 }
121
122 last_sequence = ts.tv_sec;
123 return last_sequence;
124 }
125
126 uint32_t frr_sequence32_next(void)
127 {
128 /* coverity[Y2K38_SAFETY] */
129 return (uint32_t)frr_sequence_next();
130 }