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>
17 /* helper for afs_exec_alt; just constructs the string for the 'alternate'
20 construct_alt(const char *argv0
, const char *prefix
, const char *suffix
)
22 size_t prefix_len
= strlen(prefix
);
23 size_t suffix_len
= strlen(suffix
);
27 alt
= malloc(strlen(argv0
) + prefix_len
+ suffix_len
+ 1);
33 replace
= strrchr(alt
, '/');
40 replace_len
= strlen(replace
);
42 memmove(replace
+ prefix_len
, replace
, replace_len
);
43 memcpy(replace
, prefix
, prefix_len
);
44 /* basically strcat(replace, suffix), but a touch faster */
45 memcpy(replace
+ prefix_len
+ replace_len
, suffix
, suffix_len
+ 1);
51 * execute an alternate version of the running program.
53 * This takes the current argc/argv, and executes an "anternate" version
54 * of the current program ("alternate" meaning e.g. DAFS/non-DAFS,
55 * 32-bit/64-bit, etc). For example, if the current running program is
56 * fssync-debug, running afs_exec_alt(argc, argc, "da", NULL) will try
57 * to execute a "dafssync-debug" program, if it can be run.
59 * @param[in] argc argc for the current program
60 * @param[in] argv argv for the current program
61 * @param[in] prefix prefix for the alternate program (or NULL)
62 * @param[in] suffix suffix for the alternate program (or NULL)
64 * @return the program that we failed to run, or NULL if we failed
65 * before constructing it. This string must be freed by the caller
67 * @pre at least one of 'prefix' or 'suffix' is non-NULL and non-empty
69 * @note if successful, never returns
72 afs_exec_alt(int argc
, char **argv
, const char *prefix
, const char *suffix
)
86 if (prefix
[0] == '\0' && suffix
[0] == '\0') {
87 /* we'd be exec'ing ourselves; that's no good */
92 targv
= malloc(sizeof(char*) * (argc
+1));
97 targv
[0] = construct_alt(argv
[0], prefix
, suffix
);
102 for (i
= 1; i
< argc
; i
++) {
103 targv
[i
] = strdup(argv
[i
]);
110 execvp(targv
[0], targv
);
113 /* we only call free() beyond this point, which I don't think would ever
114 * muck with errno, but I don't trust everyone's libc... */
118 for (; i
>= 1; i
--) {