File: snprinterr.c

package info (click to toggle)
socat 1.7.3.2-2
  • links: PTS
  • area: main
  • in suites: bullseye, buster, sid
  • size: 3,888 kB
  • sloc: ansic: 28,032; sh: 11,782; makefile: 146
file content (85 lines) | stat: -rw-r--r-- 2,348 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/* snprinterr.c */
/* Copyright Gerhard Rieger and contributors (see file CHANGES) */

/* a function similar to vsnprintf() but it just handles %m */

#include "config.h"

#include <stddef.h>	/* ptrdiff_t */
#include <ctype.h>	/* isdigit() */
#include <stdarg.h>
#include <stdlib.h>
#include <errno.h>
#if HAVE_SYSLOG_H
#include <syslog.h>
#endif
#include <sys/utsname.h>
#include <time.h>	/* time_t, strftime() */
#include <sys/time.h>	/* gettimeofday() */
#include <stdio.h>
#include <string.h>
#if HAVE_UNISTD_H
#include <unistd.h>
#endif

#include "snprinterr.h"

#define HAVE_STRERROR_R 0
/* replace %m in format with actual strerror() message, write result to *str.
   keep other % formats unchanged!
   writes at most size chars including the terminating \0 to *str
   returns the number of bytes in the output without terminating \0
   result is always \0 terminated except when size==0
 */
int snprinterr(char *str, size_t size, const char *format) {
   char c;
   int full = 0;	/* 1 means: there is no space left in * str for more data or \0 */
   int count = 0;
   if (size == 0)  return 0;
   if (count >= size)  full = 1;
   while (c = *format++) {
      if (c == '%') {
	 c = *format++;
	 switch (c) {
	 case '\0':
	    ++count; if (!full) { (*str++ = '%'); if (count+1 >= size) full = 1; }
	    break;
	 default:
	    ++count; if (!full) { (*str++ = '%'); if (count+1 >= size) full = 1; }
	    ++count; if (!full) { (*str++ = c);   if (count+1 >= size) full = 1; }
	    break;
	 case 'm':
	    {
#if HAVE_STRERROR_R
#              define BUFLEN 64
	       char buf[BUFLEN] = "";
#endif /* HAVE_STRERROR_R */
	       char *bufp;
#if !HAVE_STRERROR_R
	       bufp = strerror(errno);
#else
	       /* there are two versions floating around... */
#  if 1	/* GNU version */
	       bufp = strerror_r(errno, buf, BUFLEN);
#  else	/* standard version */
	       strerror_r(errno, buf, BUFLEN);
	       bufp = buf;
#  endif
#endif /* HAVE_STRERROR_R */
	       while ((c = *bufp++) != '\0') {
		  ++count; if (!full) { (*str++ = c);   if (count+1 >= size) full = 1; }
	       }
	    }
	    c = ' ';	/* not \0 ! */
	    break;
	 }
	 if (c == '\0')  break;
      } else {
	 ++count; if (!full) { (*str++ = c); if (count+1 >= size)  full = 1; }
      }
   }
   *str++ = '\0';	/* always write terminating \0 */
   return count;
#undef BUFLEN
}