comparison lib/portability.c @ 549:1f5bd8c93093

Implement Apple and Android versions of getline(), getdelim(), and clearenv().
author Georgi Chorbadzhiyski <gf@unixsol.org>
date Fri, 16 Mar 2012 06:42:08 -0500
parents
children 786841fdb1e0
comparison
equal deleted inserted replaced
548:99cb6ad605ee 549:1f5bd8c93093
1 /* vi: set sw=4 ts=4 :*/
2 /* portability.c - code to workaround the deficiencies of various platforms.
3 *
4 * Copyright 2012 Rob Landley <rob@landley.net>
5 * Copyright 2012 Georgi Chorbadzhiyski <gf@unixsol.org>
6 */
7
8 #include "toys.h"
9
10 #if defined(__APPLE__) || defined(__ANDROID__)
11 ssize_t getdelim(char **linep, size_t *np, int delim, FILE *stream)
12 {
13 int ch;
14 size_t new_len;
15 ssize_t i = 0;
16 char *line, *new_line;
17
18 // Invalid input
19 if (!linep || !np) {
20 errno = EINVAL;
21 return -1;
22 }
23
24 if (*linep == NULL || *np == 0) {
25 *np = 1024;
26 *linep = calloc(1, *np);
27 if (*linep == NULL)
28 return -1;
29 }
30 line = *linep;
31
32 while ((ch = getc(stream)) != EOF) {
33 if (i > *np) {
34 // Need more space
35 new_len = *np + 1024;
36 new_line = realloc(*linep, new_len);
37 if (!new_line)
38 return -1;
39 *np = new_len;
40 *linep = new_line;
41 }
42
43 line[i] = ch;
44 if (ch == delim)
45 break;
46 i += 1;
47 }
48
49 if (i > *np) {
50 // Need more space
51 new_len = i + 2;
52 new_line = realloc(*linep, new_len);
53 if (!new_line)
54 return -1;
55 *np = new_len;
56 *linep = new_line;
57 }
58 line[i + 1] = '\0';
59
60 return i > 0 ? i : -1;
61 }
62
63 ssize_t getline(char **linep, size_t *np, FILE *stream) {
64 return getdelim(linep, np, '\n', stream);
65 }
66 #endif
67
68 #if defined(__APPLE__)
69 extern char **environ;
70
71 int clearenv(void) {
72 *environ = NULL;
73 return 0;
74 }
75 #endif