2 mtr -- a network diagnostic tool
3 Copyright (C) 1997,1998 Matt Kimball
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License version 2 as
7 published by the Free Software Foundation.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation, Inc.,
16 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
34 #include "portability/error.h"
37 #ifdef HAVE_STDIO_EXT_H
38 #include <stdio_ext.h>
51 while (*p
&& (isspace((unsigned char) *p
) || (c
&& *p
== c
)))
55 memmove(str
, p
, len
+ 1);
62 if (isspace((unsigned char) str
[len
]) || (c
&& str
[len
] == c
)) {
72 /* Parse string, and return positive signed int. */
78 unsigned long int num
;
81 if (str
!= NULL
&& *str
!= '\0') {
83 num
= strtoul(str
, &end
, 0);
84 if (errno
== 0 && str
!= end
&& end
!= NULL
&& *end
== '\0') {
97 error(EXIT_FAILURE
, errno
, "%s: '%s'", errmesg
, str
);
101 float strtofloat_or_err(
108 if (str
!= NULL
&& *str
!= '\0') {
110 num
= strtod(str
, &end
);
111 if (errno
== 0 && str
!= end
&& end
!= NULL
&& *end
== '\0'
118 error(EXIT_FAILURE
, errno
, "%s: '%s'", errmesg
, str
);
125 void *ret
= malloc(size
);
128 error(EXIT_FAILURE
, errno
, "cannot allocate %zu bytes", size
);
141 error(EXIT_FAILURE
, errno
, "cannot duplicate string: %s", str
);
145 #ifndef HAVE___FPENDING
146 static inline int __fpending(
147 FILE * stream
__attribute__ ((__unused__
)))
152 static inline int close_stream(
155 const int some_pending
= (__fpending(stream
) != 0);
156 const int prev_fail
= (ferror(stream
) != 0);
157 const int fclose_fail
= (fclose(stream
) != 0);
159 if (prev_fail
|| (fclose_fail
&& (some_pending
|| errno
!= EBADF
))) {
160 if (!fclose_fail
&& !(errno
== EPIPE
))
167 /* Meant to be used atexit(close_stdout); */
171 if (close_stream(stdout
) != 0 && !(errno
== EPIPE
)) {
172 error(0, errno
, "write error");
175 if (close_stream(stderr
) != 0)
179 /* ctime() replacement that will return ISO-8601 timestamp string such as:
180 * 2016-08-29T19:25:02+01:00 */
181 const char *iso_time(
188 strftime(s
, sizeof(s
), "%Y-%m-%dT%H:%M:%S%z", tm
);