2 * Copyright 2010, Sine Nomine Associates and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 /* exec-related helper routines */
12 #include <afsconfig.h>
13 #include <afs/param.h>
20 /* helper for afs_exec_alt; just constructs the string for the 'alternate'
23 construct_alt(const char *argv0, const char *prefix, const char *suffix)
25 size_t prefix_len = strlen(prefix);
26 size_t suffix_len = strlen(suffix);
30 alt = malloc(strlen(argv0) + prefix_len + suffix_len + 1);
36 replace = strrchr(alt, '/');
43 replace_len = strlen(replace);
45 memmove(replace + prefix_len, replace, replace_len);
46 memcpy(replace, prefix, prefix_len);
47 /* basically strcat(replace, suffix), but a touch faster */
48 memcpy(replace + prefix_len + replace_len, suffix, suffix_len);
54 * execute an alternate version of the running program.
56 * This takes the current argc/argv, and executes an "anternate" version
57 * of the current program ("alternate" meaning e.g. DAFS/non-DAFS,
58 * 32-bit/64-bit, etc). For example, if the current running program is
59 * fssync-debug, running afs_exec_alt(argc, argc, "da", NULL) will try
60 * to execute a "dafssync-debug" program, if it can be run.
62 * @param[in] argc argc for the current program
63 * @param[in] argv argv for the current program
64 * @param[in] prefix prefix for the alternate program (or NULL)
65 * @param[in] suffix suffix for the alternate program (or NULL)
67 * @return the program that we failed to run, or NULL if we failed
68 * before constructing it. This string must be freed by the caller
70 * @pre at least one of 'prefix' or 'suffix' is non-NULL and non-empty
72 * @note if successful, never returns
75 afs_exec_alt(int argc, char **argv, const char *prefix, const char *suffix)
89 if (prefix[0] == '\0' && suffix[0] == '\0') {
90 /* we'd be exec'ing ourselves; that's no good */
95 targv = malloc(sizeof(char*) * (argc+1));
100 targv[0] = construct_alt(argv[0], prefix, suffix);
105 for (i = 1; i < argc; i++) {
106 targv[i] = strdup(argv[i]);
113 execvp(targv[0], targv);
116 /* we only call free() beyond this point, which I don't think would ever
117 * muck with errno, but I don't trust everyone's libc... */
121 for (; i >= 1; i--) {