1#define _GNU_SOURCE /* See feature_test_macros(7) */ 2#include <unistd.h> 3#include <stdlib.h> 4#include <assert.h> 5#include <stdio.h> 6 7#define assert_success(e) do { if ((e) < 0) { perror(#e); abort(); } } while (0) 8 9void set_env_prefix(char *env, char *sep, char *prefix) { 10 char *existing = getenv(env); 11 if (existing) { 12 char *val; 13 assert_success(asprintf(&val, "%s%s%s", prefix, sep, existing)); 14 assert_success(setenv(env, val, 1)); 15 free(val); 16 } else { 17 assert_success(setenv(env, prefix, 1)); 18 } 19} 20 21void set_env_suffix(char *env, char *sep, char *suffix) { 22 char *existing = getenv(env); 23 if (existing) { 24 char *val; 25 assert_success(asprintf(&val, "%s%s%s", existing, sep, suffix)); 26 assert_success(setenv(env, val, 1)); 27 free(val); 28 } else { 29 assert_success(setenv(env, suffix, 1)); 30 } 31} 32 33int main(int argc, char **argv) { 34 assert_success(setenv("MESSAGE", "HELLO", 0)); 35 set_env_prefix("PATH", ":", "/usr/bin/"); 36 set_env_suffix("PATH", ":", "/usr/local/bin/"); 37 putenv("MESSAGE2=WORLD"); 38 39 char **argv_tmp = calloc(3 + argc + 0 + 1, sizeof(*argv_tmp)); 40 assert(argv_tmp != NULL); 41 argv_tmp[0] = argv[0]; 42 argv_tmp[1] = "-x"; 43 argv_tmp[2] = "-y"; 44 argv_tmp[3] = "-z"; 45 for (int i = 1; i < argc; ++i) { 46 argv_tmp[3 + i] = argv[i]; 47 } 48 argv_tmp[3 + argc + 0] = NULL; 49 argv = argv_tmp; 50 51 argv[0] = "my-wrapper"; 52 return execv("/send/me/flags", argv); 53}