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