Line | Count | Source |
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 | 0 | { |
15 | 0 | int nleft; |
16 | 0 | int nread; |
17 | |
|
18 | 0 | nleft = nbytes; |
19 | |
|
20 | 0 | while (nleft > 0) { |
21 | 0 | nread = read(fd, ptr, nleft); |
22 | |
|
23 | 0 | if (nread < 0) |
24 | 0 | return (nread); |
25 | 0 | else if (nread == 0) |
26 | 0 | break; |
27 | | |
28 | 0 | nleft -= nread; |
29 | 0 | ptr += nread; |
30 | 0 | } |
31 | | |
32 | 0 | return nbytes - nleft; |
33 | 0 | } |
34 | | |
35 | | /* Write nbytes from ptr to fd. */ |
36 | | int writen(int fd, const uint8_t *ptr, int nbytes) |
37 | 0 | { |
38 | 0 | int nleft; |
39 | 0 | int nwritten; |
40 | |
|
41 | 0 | nleft = nbytes; |
42 | |
|
43 | 0 | while (nleft > 0) { |
44 | 0 | nwritten = write(fd, ptr, nleft); |
45 | |
|
46 | 0 | if (nwritten < 0) { |
47 | 0 | if (!ERRNO_IO_RETRY(errno)) |
48 | 0 | return nwritten; |
49 | 0 | } |
50 | 0 | if (nwritten == 0) |
51 | 0 | return (nwritten); |
52 | | |
53 | 0 | nleft -= nwritten; |
54 | 0 | ptr += nwritten; |
55 | 0 | } |
56 | 0 | return nbytes - nleft; |
57 | 0 | } |
58 | | |
59 | | int set_nonblocking(int fd) |
60 | 8 | { |
61 | 8 | int flags; |
62 | | |
63 | | /* According to the Single UNIX Spec, the return value for F_GETFL |
64 | | should |
65 | | never be negative. */ |
66 | 8 | flags = fcntl(fd, F_GETFL); |
67 | 8 | if (flags < 0) { |
68 | 0 | flog_err(EC_LIB_SYSTEM_CALL, |
69 | 0 | "fcntl(F_GETFL) failed for fd %d: %s", fd, |
70 | 0 | safe_strerror(errno)); |
71 | 0 | return -1; |
72 | 0 | } |
73 | 8 | if (fcntl(fd, F_SETFL, (flags | O_NONBLOCK)) < 0) { |
74 | 0 | flog_err(EC_LIB_SYSTEM_CALL, |
75 | 0 | "fcntl failed setting fd %d non-blocking: %s", fd, |
76 | 0 | safe_strerror(errno)); |
77 | 0 | return -1; |
78 | 0 | } |
79 | 8 | return 0; |
80 | 8 | } |
81 | | |
82 | | int set_cloexec(int fd) |
83 | 0 | { |
84 | 0 | int flags; |
85 | 0 | flags = fcntl(fd, F_GETFD, 0); |
86 | 0 | if (flags == -1) |
87 | 0 | return -1; |
88 | | |
89 | 0 | flags |= FD_CLOEXEC; |
90 | 0 | if (fcntl(fd, F_SETFD, flags) == -1) |
91 | 0 | return -1; |
92 | 0 | return 0; |
93 | 0 | } |
94 | | |
95 | | float htonf(float host) |
96 | 0 | { |
97 | 0 | uint32_t lu1, lu2; |
98 | 0 | float convert; |
99 | |
|
100 | 0 | memcpy(&lu1, &host, sizeof(uint32_t)); |
101 | 0 | lu2 = htonl(lu1); |
102 | 0 | memcpy(&convert, &lu2, sizeof(uint32_t)); |
103 | 0 | return convert; |
104 | 0 | } |
105 | | |
106 | | float ntohf(float net) |
107 | 0 | { |
108 | 0 | return htonf(net); |
109 | 0 | } |
110 | | |
111 | | uint64_t frr_sequence_next(void) |
112 | 1 | { |
113 | 1 | static uint64_t last_sequence; |
114 | 1 | struct timespec ts; |
115 | | |
116 | 1 | (void)clock_gettime(CLOCK_MONOTONIC, &ts); |
117 | 1 | if (last_sequence == (uint64_t)ts.tv_sec) { |
118 | 0 | last_sequence++; |
119 | 0 | return last_sequence; |
120 | 0 | } |
121 | | |
122 | 1 | last_sequence = ts.tv_sec; |
123 | 1 | return last_sequence; |
124 | 1 | } |
125 | | |
126 | | uint32_t frr_sequence32_next(void) |
127 | 1 | { |
128 | | /* coverity[Y2K38_SAFETY] */ |
129 | 1 | return (uint32_t)frr_sequence_next(); |
130 | 1 | } |