Annotation of embedaddon/mtr/ui/utils.c, revision 1.1.1.3

1.1       misho       1: /*
                      2:     mtr  --  a network diagnostic tool
                      3:     Copyright (C) 1997,1998  Matt Kimball
                      4: 
                      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.
                      8: 
                      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.
                     13: 
1.1.1.2   misho      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.
1.1       misho      17: */
                     18: 
                     19: #include "config.h"
                     20: 
                     21: #include <ctype.h>
                     22: #include <errno.h>
                     23: #include <limits.h>
                     24: #include <stdint.h>
                     25: #include <stdio.h>
                     26: #include <stdlib.h>
                     27: #include <string.h>
                     28: #include <time.h>
                     29: #include <unistd.h>
                     30: 
                     31: #ifdef HAVE_ERROR_H
                     32: #include <error.h>
                     33: #else
                     34: #include "portability/error.h"
                     35: #endif
                     36: 
                     37: #ifdef HAVE_STDIO_EXT_H
                     38: #include <stdio_ext.h>
                     39: #endif
                     40: 
                     41: #include "utils.h"
                     42: 
                     43: char *trim(
                     44:     char *str,
                     45:     const char c)
                     46: {
                     47:     char *p = str;
                     48:     size_t len;
                     49: 
                     50:     /* left trim */
                     51:     while (*p && (isspace((unsigned char) *p) || (c && *p == c)))
                     52:         p++;
                     53:     if (str < p) {
                     54:         len = strlen(str);
                     55:         memmove(str, p, len + 1);
                     56:     }
                     57: 
                     58:     /* right trim */
                     59:     len = strlen(str);
                     60:     while (len) {
                     61:         len--;
                     62:         if (isspace((unsigned char) str[len]) || (c && str[len] == c)) {
                     63:             continue;
                     64:         }
                     65:         len++;
                     66:         break;
                     67:     }
                     68:     str[len] = '\0';
                     69:     return str;
                     70: }
                     71: 
                     72: /* Parse string, and return positive signed int. */
                     73: int strtonum_or_err(
                     74:     const char *str,
                     75:     const char *errmesg,
                     76:     const int type)
                     77: {
                     78:     unsigned long int num;
                     79:     char *end = NULL;
                     80: 
                     81:     if (str != NULL && *str != '\0') {
                     82:         errno = 0;
                     83:         num = strtoul(str, &end, 10);
                     84:         if (errno == 0 && str != end && end != NULL && *end == '\0') {
                     85:             switch (type) {
                     86:             case STRTO_INT:
                     87:                 if (num < INT_MAX)
                     88:                     return num;
                     89:                 break;
                     90:             case STRTO_U32INT:
                     91:                 if (num < UINT32_MAX)
                     92:                     return num;
                     93:                 break;
                     94:             }
                     95:         }
                     96:     }
                     97:     error(EXIT_FAILURE, errno, "%s: '%s'", errmesg, str);
                     98:     return 0;
                     99: }
                    100: 
                    101: float strtofloat_or_err(
                    102:     const char *str,
                    103:     const char *errmesg)
                    104: {
                    105:     double num;
                    106:     char *end = NULL;
                    107: 
                    108:     if (str != NULL && *str != '\0') {
                    109:         errno = 0;
                    110:         num = strtod(str, &end);
                    111:         if (errno == 0 && str != end && end != NULL && *end == '\0'
                    112: #ifdef FLT_MAX
                    113:             && num < FLT_MAX
                    114: #endif
                    115:             )
                    116:             return num;
                    117:     }
                    118:     error(EXIT_FAILURE, errno, "%s: '%s'", errmesg, str);
                    119:     return 0;
                    120: }
                    121: 
                    122: void *xmalloc(
                    123:     const size_t size)
                    124: {
                    125:     void *ret = malloc(size);
                    126: 
                    127:     if (!ret && size)
                    128:         error(EXIT_FAILURE, errno, "cannot allocate %zu bytes", size);
                    129:     return ret;
                    130: }
                    131: 
                    132: char *xstrdup(
                    133:     const char *str)
                    134: {
                    135:     char *ret;
                    136: 
                    137:     if (!str)
                    138:         return NULL;
                    139:     ret = strdup(str);
                    140:     if (!ret)
                    141:         error(EXIT_FAILURE, errno, "cannot duplicate string: %s", str);
                    142:     return ret;
                    143: }
                    144: 
                    145: #ifndef HAVE___FPENDING
                    146: static inline int __fpending(
                    147:     FILE * stream __attribute__ ((__unused__)))
                    148: {
                    149:     return 0;
                    150: }
                    151: #endif
                    152: static inline int close_stream(
                    153:     FILE * stream)
                    154: {
                    155:     const int some_pending = (__fpending(stream) != 0);
                    156:     const int prev_fail = (ferror(stream) != 0);
                    157:     const int fclose_fail = (fclose(stream) != 0);
                    158: 
                    159:     if (prev_fail || (fclose_fail && (some_pending || errno != EBADF))) {
                    160:         if (!fclose_fail && !(errno == EPIPE))
                    161:             errno = 0;
                    162:         return EOF;
                    163:     }
                    164:     return 0;
                    165: }
                    166: 
                    167: /* Meant to be used atexit(close_stdout); */
                    168: void close_stdout(
                    169:     void)
                    170: {
                    171:     if (close_stream(stdout) != 0 && !(errno == EPIPE)) {
                    172:         error(0, errno, "write error");
                    173:         _exit(EXIT_FAILURE);
                    174:     }
                    175:     if (close_stream(stderr) != 0)
                    176:         _exit(EXIT_FAILURE);
                    177: }
                    178: 
1.1.1.3 ! misho     179: /* ctime() replacement that will return ISO-8601 timestamp string such as:
1.1       misho     180:  * 2016-08-29T19:25:02+01:00 */
                    181: const char *iso_time(
                    182:     const time_t * t)
                    183: {
                    184:     static char s[32];
                    185:     struct tm *tm;
                    186: 
                    187:     tm = localtime(t);
                    188:     strftime(s, sizeof(s), "%Y-%m-%dT%H:%M:%S%z", tm);
                    189:     return s;
                    190: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>