| @@ -17,53 +17,80 @@ | | | @@ -17,53 +17,80 @@ |
17 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | | 17 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
18 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | | 18 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
19 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | | 19 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
20 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | | 20 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
21 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | | 21 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
27 | * POSSIBILITY OF SUCH DAMAGE. | | 27 | * POSSIBILITY OF SUCH DAMAGE. |
28 | */ | | 28 | */ |
29 | | | 29 | |
| | | 30 | #include <sys/param.h> |
30 | #include <stdio.h> | | 31 | #include <stdio.h> |
31 | #include <stdlib.h> | | 32 | #include <stdlib.h> |
32 | #include <string.h> | | 33 | #include <string.h> |
33 | #include <stdarg.h> | | 34 | #include <stdarg.h> |
| | | 35 | #include <limits.h> |
| | | 36 | #include <unistd.h> |
34 | | | 37 | |
35 | #ifdef NEED_SETPROCTITLE | | 38 | #ifdef NEED_SETPROCTITLE |
36 | | | 39 | |
37 | extern char **__environ; | | 40 | extern char **__environ; |
38 | | | 41 | |
39 | void | | 42 | void |
40 | setproctitle(const char *fmt, ...) | | 43 | setproctitle(const char *fmt, ...) |
41 | { | | 44 | { |
42 | va_list ap; | | 45 | va_list ap; |
43 | char buf[1024]; | | 46 | char buf[1024]; |
44 | int len; | | 47 | int len; |
45 | char *pname, *p; | | 48 | char *pname, *p, *s; |
46 | char **args = __environ - 2; | | 49 | /* |
| | | 50 | * Assumes that stack grows down, and than environ has not bee |
| | | 51 | * reallocated because of setenv() required growth. Stack layout: |
| | | 52 | * |
| | | 53 | * argc |
| | | 54 | * argv[0] |
| | | 55 | * ... |
| | | 56 | * argv[n] |
| | | 57 | * NULL |
| | | 58 | * environ[0] |
| | | 59 | * ... |
| | | 60 | * environ[n] |
| | | 61 | * NULL |
| | | 62 | */ |
47 | | | 63 | |
| | | 64 | /* 1 for the first entry, 1 for the NULL */ |
| | | 65 | char **args = __environ - 2, *s; |
| | | 66 | #ifdef _SC_ARG_MAX |
| | | 67 | s = (char *)sysconf(_SC_ARG_MAX); |
| | | 68 | #elifdef ARG_MAX |
| | | 69 | s = (char *)ARG_MAX; |
| | | 70 | #elifdef NCARGS |
| | | 71 | s = (char *)NCARGS; |
| | | 72 | #else |
| | | 73 | s = (char *)(256 * 1024); |
| | | 74 | #endif |
48 | /* | | 75 | /* |
49 | * Keep going while it looks like a pointer. We'll stop at argc, | | 76 | * Keep going while it looks like a pointer. We'll stop at argc, |
50 | * Assume that we have < 10K args. | | 77 | * Which is a lot smaller than a pointer, limited by ARG_MAX |
51 | */ | | 78 | */ |
52 | while (*args > (char *)10240) | | 79 | while (*args > s) |
53 | args--; | | 80 | args--; |
54 | | | 81 | |
55 | pname = *++args; | | 82 | *(int *)args = 1; /* *argc = 1; */ |
56 | *(int *)((int *)pname - 1) = 1; /* *argc = 1; */ | | 83 | pname = *++args; /* pname = argv[0] */ |
57 | | | 84 | |
58 | /* Just the last component of the name */ | | 85 | /* Just the last component of the name */ |
59 | if ((p = strrchr(pname, '/')) != NULL) | | 86 | if ((p = strrchr(pname, '/')) != NULL) |
60 | pname = p + 1; | | 87 | pname = p + 1; |
61 | | | 88 | |
62 | /* In case we get called again */ | | 89 | /* In case we get called again */ |
63 | if ((p = strrchr(pname, ':')) != NULL) | | 90 | if ((p = strrchr(pname, ':')) != NULL) |
64 | *p = '\0'; | | 91 | *p = '\0'; |
65 | | | 92 | |
66 | va_start(ap, fmt); | | 93 | va_start(ap, fmt); |
67 | if (fmt != NULL) { | | 94 | if (fmt != NULL) { |
68 | len = snprintf(buf, sizeof(buf), "%s: ", pname); | | 95 | len = snprintf(buf, sizeof(buf), "%s: ", pname); |
69 | if (len >= 0) | | 96 | if (len >= 0) |