blob: 70ebece306a1a46c30e12d5eecf1122840e075ee [file] [log] [blame]
Michal Vasko9e8ac262020-04-07 13:06:45 +02001/**
2 * @file compat.c
3 * @author Michal Vasko <mvasko@cesnet.cz>
4 * @brief compatibility functions
5 *
6 * Copyright (c) 2020 CESNET, z.s.p.o.
7 *
8 * This source code is licensed under BSD 3-Clause License (the "License").
9 * You may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * https://opensource.org/licenses/BSD-3-Clause
13 */
14#define _POSIX_C_SOURCE 1 /* fdopen, _POSIX_PATH_MAX */
15#define _ISOC99_SOURCE /* vsnprintf */
16#define _XOPEN_SOURCE 500 /* strdup */
17
18#include <errno.h>
19#include <limits.h>
20#include <string.h>
21#include <stdarg.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include <unistd.h>
25
26#include "compat.h"
27
28#ifndef HAVE_VDPRINTF
29int
30vdprintf(int fd, const char *format, va_list ap)
31{
32 FILE *stream;
33 int count;
34
35 stream = fdopen(dup(fd), "a+");
36 if (stream) {
37 count = vfprintf(stream, format, ap);
38 fclose(stream);
39 }
40 return count;
41}
42#endif
43
44#ifndef HAVE_ASPRINTF
45int
46asprintf(char **strp, const char *fmt, ...)
47{
48 int ret;
49 va_list ap;
50
51 va_start(ap, fmt);
52 ret = vasprintf(strp, fmt, ap);
53 va_end(ap);
54 return ret;
55}
56#endif
57
58#ifndef HAVE_VASPRINTF
59int
60vasprintf(char **strp, const char *fmt, va_list ap)
61{
62 va_list ap2;
63 va_copy(ap2, ap);
64 int l = vsnprintf(0, 0, fmt, ap2);
65 va_end(ap2);
66
67 if (l < 0 || !(*strp = malloc(l + 1U))) {
68 return -1;
69 }
70
71 return vsnprintf(*strp, l + 1U, fmt, ap);
72}
73#endif
74
75#ifndef HAVE_STRNDUP
76char *
77strndup(const char *s, size_t n)
78{
79 char *buf;
80 size_t len = 0;
81
82 /* strnlen */
83 for (; (len < n) && (s[len] != '\0'); ++len);
84
85 if (!(buf = malloc(len + 1U))) {
86 return NULL;
87 }
88
89 memcpy(buf, s, len);
90 buf[len] = '\0';
91 return buf;
92}
93#endif
94
95#ifndef HAVE_GETLINE
96ssize_t
97getline(char **lineptr, size_t *n, FILE *stream)
98{
99 static char line[256];
100 char *ptr;
101 unsigned int len;
102
103 if (!lineptr || !n) {
104 errno = EINVAL;
105 return -1;
106 }
107
108 if (ferror(stream) || feof(stream)) {
109 return -1;
110 }
111
112 if (!fgets(line, 256, stream)) {
113 return -1;
114 }
115
116 ptr = strchr(line, '\n');
117 if (ptr) {
118 *ptr = '\0';
119 }
120
121 len = strlen(line);
122
123 if (len + 1 < 256) {
124 ptr = realloc(*lineptr, 256);
125 if (!ptr) {
126 return -1;
127 }
128 *lineptr = ptr;
129 *n = 256;
130 }
131
132 strcpy(*lineptr, line);
133 return len;
134}
135#endif
136
137#ifndef HAVE_GET_CURRENT_DIR_NAME
138char *
139get_current_dir_name(void)
140{
141 char tmp[_POSIX_PATH_MAX];
142 char *retval = NULL;
143
144 if (getcwd(tmp, sizeof(tmp))) {
145 retval = strdup(tmp);
146 if (!retval) {
147 errno = ENOMEM;
148 }
149 }
150
151 return retval;
152}
153#endif