2 * Copyright © 2013 Guillem Jover <guillem@hadrons.org>
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. The name of the author may not be used to endorse or promote products
13 * derived from this software without specific prior written permission.
15 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
16 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
17 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
18 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 #include <sys/param.h>
42 /* Title space available. */
45 /* Pointer to original nul character within base. */
53 #define LIBBSD_IS_PATHNAME_SEPARATOR(c) ((c) == '/')
54 #define SPT_MAXTITLE 255
56 extern const char *__progname
;
65 setprogname(const char *progname
)
69 for (i
= strlen(progname
); i
> 0; i
--) {
70 if (LIBBSD_IS_PATHNAME_SEPARATOR(progname
[i
- 1])) {
71 __progname
= progname
+ i
;
75 __progname
= progname
;
80 spt_min(size_t a
, size_t b
)
82 return ((a
< b
) ? a
: b
);
86 spt_copyenv(int envc
, char *envp
[])
97 * Make a copy of the old environ array of pointers, in case
98 * clearenv() or setenv() is implemented to free the internal
99 * environ array, because we will need to access the old environ
100 * contents to make the new copy.
102 envsize
= (envc
+ 1) * sizeof (char *);
103 envcopy
= malloc(envsize
);
106 memcpy(envcopy
, envp
, envsize
);
110 for (i
= 0; envcopy
[i
]; i
++) {
111 eq
= strchr(envcopy
[i
], '=');
116 if (setenv(envcopy
[i
], eq
+ 1, 1) < 0)
129 * Dispose of the shallow copy, now that we've finished transfering
130 * the old environment.
138 spt_copyargs(int argc
, char *argv
[])
143 for (i
= 1; i
< argc
|| (i
>= argc
&& argv
[i
]); i
++) {
147 tmp
= strdup(argv
[i
]);
158 zfs_setproctitle_init(int argc
, char *argv
[], char *envp
[])
160 char *base
, *end
, *nul
, *tmp
;
163 /* Try to make sure we got called with main() arguments. */
171 nul
= base
+ strlen(base
);
174 for (i
= 0; i
< argc
|| (i
>= argc
&& argv
[i
]); i
++) {
175 if (argv
[i
] == NULL
|| argv
[i
] != end
)
178 end
= argv
[i
] + strlen(argv
[i
]) + 1;
181 for (i
= 0; envp
[i
]; i
++) {
185 end
= envp
[i
] + strlen(envp
[i
]) + 1;
189 SPT
.arg0
= strdup(argv
[0]);
190 if (SPT
.arg0
== NULL
) {
195 tmp
= strdup(getprogname());
202 error
= spt_copyenv(envc
, envp
);
208 error
= spt_copyargs(argc
, argv
);
220 zfs_setproctitle(const char *fmt
, ...)
222 /* Use buffer in case argv[0] is passed. */
223 char buf
[SPT_MAXTITLE
+ 1];
227 if (SPT
.base
== NULL
) {
229 warnx("setproctitle not initialized, please"
230 "call zfs_setproctitle_init()");
238 /* Skip program name prefix. */
242 /* Print program name heading for grep. */
243 snprintf(buf
, sizeof (buf
), "%s: ", getprogname());
248 len
+= vsnprintf(buf
+ len
, sizeof (buf
) - len
, fmt
, ap
);
251 len
= snprintf(buf
, sizeof (buf
), "%s", SPT
.arg0
);
260 memset(SPT
.base
, 0, SPT
.end
- SPT
.base
);
263 memset(SPT
.base
, 0, spt_min(sizeof (buf
), SPT
.end
- SPT
.base
));
266 len
= spt_min(len
, spt_min(sizeof (buf
), SPT
.end
- SPT
.base
) - 1);
267 memcpy(SPT
.base
, buf
, len
);
268 nul
= SPT
.base
+ len
;
272 } else if (nul
== SPT
.nul
&& nul
+ 1 < SPT
.end
) {