summaryrefslogtreecommitdiffstats
path: root/gl/af_alg.c
diff options
context:
space:
mode:
authorLorenz Kästle <12514511+RincewindsHat@users.noreply.github.com>2026-03-26 12:53:53 +0100
committerGitHub <noreply@github.com>2026-03-26 12:53:53 +0100
commit13e14a6bfd9f29cbfeab0c5161d2a994f97532e7 (patch)
tree3aa7186fe092e42783dc7e981dc39a74ea61c466 /gl/af_alg.c
parent9d8503f90ef25b2cecd324dc118e441f40233ea8 (diff)
downloadmonitoring-plugins-13e14a6bfd9f29cbfeab0c5161d2a994f97532e7.tar.gz
Update/gnulib 2026 03 (#2247)HEADmaster
* Sync with the 202601-stable Gnulib code (4a3650d887) * Ignore more deps stuff in gnulib * Remove autogenerated gnulib files * Ignore more gnulib generated headers
Diffstat (limited to 'gl/af_alg.c')
-rw-r--r--gl/af_alg.c188
1 files changed, 95 insertions, 93 deletions
diff --git a/gl/af_alg.c b/gl/af_alg.c
index cfa96954..91f3df15 100644
--- a/gl/af_alg.c
+++ b/gl/af_alg.c
@@ -1,5 +1,5 @@
1/* af_alg.c - Compute message digests from file streams and buffers. 1/* af_alg.c - Compute message digests from file streams and buffers.
2 Copyright (C) 2018-2025 Free Software Foundation, Inc. 2 Copyright (C) 2018-2026 Free Software Foundation, Inc.
3 3
4 This file is free software: you can redistribute it and/or modify 4 This file is free software: you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as 5 it under the terms of the GNU Lesser General Public License as
@@ -112,100 +112,102 @@ afalg_stream (FILE *stream, const char *alg,
112 read-write loop work around an empty-input bug noted below. */ 112 read-write loop work around an empty-input bug noted below. */
113 int fd = fileno (stream); 113 int fd = fileno (stream);
114 int result; 114 int result;
115 struct stat st; 115 {
116 off_t off = ftello (stream); 116 struct stat st;
117 if (0 <= off && fstat (fd, &st) == 0 117 off_t off = ftello (stream);
118 && (S_ISREG (st.st_mode) || S_TYPEISSHM (&st) || S_TYPEISTMO (&st)) 118 if (0 <= off && fstat (fd, &st) == 0
119 && off < st.st_size && st.st_size - off < SYS_BUFSIZE_MAX) 119 && (S_ISREG (st.st_mode) || S_TYPEISSHM (&st) || S_TYPEISTMO (&st))
120 { 120 && off < st.st_size && st.st_size - off < SYS_BUFSIZE_MAX)
121 /* Make sure the offset of fileno (stream) reflects how many bytes 121 {
122 have been read from stream before this function got invoked. 122 /* Make sure the offset of fileno (stream) reflects how many bytes
123 Note: fflush on an input stream after ungetc does not work as expected 123 have been read from stream before this function got invoked.
124 on some platforms. Therefore this situation is not supported here. */ 124 Note: fflush on an input stream after ungetc does not work as expected
125 if (fflush (stream)) 125 on some platforms. Therefore this situation is not supported here. */
126 result = -EIO; 126 if (fflush (stream))
127 else 127 result = -EIO;
128 { 128 else
129 off_t nbytes = st.st_size - off; 129 {
130 if (sendfile (ofd, fd, &off, nbytes) == nbytes) 130 off_t nbytes = st.st_size - off;
131 { 131 if (sendfile (ofd, fd, &off, nbytes) == nbytes)
132 if (read (ofd, resblock, hashlen) == hashlen) 132 {
133 { 133 if (read (ofd, resblock, hashlen) == hashlen)
134 /* The input buffers of stream are no longer valid. */ 134 {
135 if (lseek (fd, off, SEEK_SET) != (off_t)-1) 135 /* The input buffers of stream are no longer valid. */
136 result = 0; 136 if (lseek (fd, off, SEEK_SET) != (off_t)-1)
137 else 137 result = 0;
138 /* The file position of fd has not changed. */ 138 else
139 /* The file position of fd has not changed. */
140 result = -EAFNOSUPPORT;
141 }
142 else
143 /* The file position of fd has not changed. */
144 result = -EAFNOSUPPORT;
145 }
146 else
147 /* The file position of fd has not changed. */
148 result = -EAFNOSUPPORT;
149 }
150 }
151 else
152 {
153 /* sendfile not possible, do a classic read-write loop. */
154
155 /* Number of bytes to seek (backwards) in case of error. */
156 off_t nseek = 0;
157
158 for (;;)
159 {
160 char buf[BLOCKSIZE];
161 /* When the stream is not seekable, start with a single-byte block,
162 so that we can use ungetc() in the case that send() fails. */
163 size_t blocksize = (nseek == 0 && off < 0 ? 1 : BLOCKSIZE);
164 ssize_t size = fread (buf, 1, blocksize, stream);
165 if (size == 0)
166 {
167 /* On Linux < 4.9, the value for an empty stream is wrong (all 0).
168 See <https://patchwork.kernel.org/patch/9308641/>.
169 This was not fixed properly until November 2016,
170 see <https://patchwork.kernel.org/patch/9434741/>. */
171 result = ferror (stream) ? -EIO : nseek == 0 ? -EAFNOSUPPORT : 0;
172 break;
173 }
174 nseek -= size;
175 if (send (ofd, buf, size, MSG_MORE) != size)
176 {
177 if (nseek == -1)
178 {
179 /* 1 byte of pushback buffer is guaranteed on stream, even
180 if stream is not seekable. */
181 ungetc ((unsigned char) buf[0], stream);
139 result = -EAFNOSUPPORT; 182 result = -EAFNOSUPPORT;
140 } 183 }
141 else 184 else if (fseeko (stream, nseek, SEEK_CUR) == 0)
142 /* The file position of fd has not changed. */ 185 /* The position of stream has been restored. */
143 result = -EAFNOSUPPORT;
144 }
145 else
146 /* The file position of fd has not changed. */
147 result = -EAFNOSUPPORT;
148 }
149 }
150 else
151 {
152 /* sendfile not possible, do a classic read-write loop. */
153
154 /* Number of bytes to seek (backwards) in case of error. */
155 off_t nseek = 0;
156
157 for (;;)
158 {
159 char buf[BLOCKSIZE];
160 /* When the stream is not seekable, start with a single-byte block,
161 so that we can use ungetc() in the case that send() fails. */
162 size_t blocksize = (nseek == 0 && off < 0 ? 1 : BLOCKSIZE);
163 ssize_t size = fread (buf, 1, blocksize, stream);
164 if (size == 0)
165 {
166 /* On Linux < 4.9, the value for an empty stream is wrong (all 0).
167 See <https://patchwork.kernel.org/patch/9308641/>.
168 This was not fixed properly until November 2016,
169 see <https://patchwork.kernel.org/patch/9434741/>. */
170 result = ferror (stream) ? -EIO : nseek == 0 ? -EAFNOSUPPORT : 0;
171 break;
172 }
173 nseek -= size;
174 if (send (ofd, buf, size, MSG_MORE) != size)
175 {
176 if (nseek == -1)
177 {
178 /* 1 byte of pushback buffer is guaranteed on stream, even
179 if stream is not seekable. */
180 ungetc ((unsigned char) buf[0], stream);
181 result = -EAFNOSUPPORT; 186 result = -EAFNOSUPPORT;
182 } 187 else
183 else if (fseeko (stream, nseek, SEEK_CUR) == 0) 188 result = -EIO;
184 /* The position of stream has been restored. */ 189 break;
185 result = -EAFNOSUPPORT; 190 }
186 else 191
187 result = -EIO; 192 /* Don't assume that EOF is sticky. See:
188 break; 193 <https://sourceware.org/PR19476>. */
189 } 194 if (feof (stream))
190 195 {
191 /* Don't assume that EOF is sticky. See: 196 result = 0;
192 <https://sourceware.org/bugzilla/show_bug.cgi?id=19476>. */ 197 break;
193 if (feof (stream)) 198 }
194 { 199 }
195 result = 0; 200
196 break; 201 if (result == 0 && read (ofd, resblock, hashlen) != hashlen)
197 } 202 {
198 } 203 if (nseek == 0 || fseeko (stream, nseek, SEEK_CUR) == 0)
199 204 /* The position of stream has been restored. */
200 if (result == 0 && read (ofd, resblock, hashlen) != hashlen) 205 result = -EAFNOSUPPORT;
201 { 206 else
202 if (nseek == 0 || fseeko (stream, nseek, SEEK_CUR) == 0) 207 result = -EIO;
203 /* The position of stream has been restored. */ 208 }
204 result = -EAFNOSUPPORT; 209 }
205 else 210 }
206 result = -EIO;
207 }
208 }
209 close (ofd); 211 close (ofd);
210 return result; 212 return result;
211} 213}