root/sapi/fpm/fpm/fpm_env.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. setenv
  2. setenv
  3. clearenv
  4. unsetenv
  5. nvmatch
  6. fpm_env_setproctitle
  7. fpm_env_init_child
  8. fpm_env_conf_wp
  9. fpm_env_init_main

   1 
   2         /* $Id: fpm_env.c,v 1.15 2008/09/18 23:19:59 anight Exp $ */
   3         /* (c) 2007,2008 Andrei Nigmatulin */
   4 
   5 #include "fpm_config.h"
   6 
   7 #ifdef HAVE_ALLOCA_H
   8 #include <alloca.h>
   9 #endif
  10 #include <stdio.h>
  11 #include <stdlib.h>
  12 #include <string.h>
  13 
  14 #include "fpm_env.h"
  15 #include "fpm.h"
  16 
  17 #ifndef HAVE_SETPROCTITLE
  18 #ifdef __linux__
  19 static char **fpm_env_argv = NULL;
  20 static size_t fpm_env_argv_len = 0;
  21 #endif
  22 #endif
  23 
  24 #ifndef HAVE_SETENV
  25 # ifdef (__sparc__ || __sparc)
  26 int setenv(char *name, char *value, int clobber) /* {{{ */
  27 {
  28         char   *malloc();
  29         char   *getenv();
  30         char   *cp;
  31 
  32         if (clobber == 0 && getenv(name) != 0) {
  33                 return 0;
  34         }
  35 
  36         if ((cp = malloc(strlen(name) + strlen(value) + 2)) == 0) {
  37                 return 1;
  38         }
  39         sprintf(cp, "%s=%s", name, value);
  40         return putenv(cp);
  41 }
  42 /* }}} */
  43 # else
  44 int setenv(char *name, char *value, int overwrite) /* {{{ */
  45 {
  46         int name_len = strlen(name);
  47         int value_len = strlen(value);
  48         char *var = alloca(name_len + 1 + value_len + 1);
  49 
  50         memcpy(var, name, name_len);
  51 
  52         var[name_len] = '=';
  53 
  54         memcpy(var + name_len + 1, value, value_len);
  55 
  56         var[name_len + 1 + value_len] = '\0';
  57 
  58         return putenv(var);
  59 }
  60 /* }}} */
  61 # endif
  62 #endif
  63 
  64 #ifndef HAVE_CLEARENV
  65 void clearenv() /* {{{ */
  66 {
  67         char **envp;
  68         char *s;
  69 
  70         /* this algo is the only one known to me
  71                 that works well on all systems */
  72         while (*(envp = environ)) {
  73                 char *eq = strchr(*envp, '=');
  74 
  75                 s = strdup(*envp);
  76 
  77                 if (eq) s[eq - *envp] = '\0';
  78 
  79                 unsetenv(s);
  80                 free(s);
  81         }
  82 
  83 }
  84 /* }}} */
  85 #endif
  86 
  87 #ifndef HAVE_UNSETENV
  88 void unsetenv(const char *name) /* {{{ */
  89 {
  90         if(getenv(name) != NULL) {
  91                 int ct = 0;
  92                 int del = 0;
  93 
  94                 while(environ[ct] != NULL) {
  95                         if (nvmatch(name, environ[ct]) != 0) del=ct; /* <--- WTF?! */
  96                         { ct++; } /* <--- WTF?! */
  97                 }
  98                 /* isn't needed free here?? */
  99                 environ[del] = environ[ct-1];
 100                 environ[ct-1] = NULL;
 101         }
 102 }
 103 /* }}} */
 104 
 105 static char * nvmatch(char *s1, char *s2) /* {{{ */
 106 {
 107         while(*s1 == *s2++)
 108         {
 109                 if(*s1++ == '=') {
 110                         return s2;
 111                 }
 112         }
 113         if(*s1 == '\0' && *(s2-1) == '=') {
 114                 return s2;
 115         }
 116         return NULL;
 117 }
 118 /* }}} */
 119 #endif
 120 
 121 void fpm_env_setproctitle(char *title) /* {{{ */
 122 {
 123 #ifdef HAVE_SETPROCTITLE
 124         setproctitle("%s", title);
 125 #else
 126 #ifdef __linux__
 127         if (fpm_env_argv != NULL && fpm_env_argv_len > strlen(SETPROCTITLE_PREFIX) + 3) {
 128                 memset(fpm_env_argv[0], 0, fpm_env_argv_len);
 129                 strncpy(fpm_env_argv[0], SETPROCTITLE_PREFIX, fpm_env_argv_len - 2);
 130                 strncpy(fpm_env_argv[0] + strlen(SETPROCTITLE_PREFIX), title, fpm_env_argv_len - strlen(SETPROCTITLE_PREFIX) - 2);
 131                 fpm_env_argv[1] = NULL;
 132         }
 133 #endif
 134 #endif
 135 }
 136 /* }}} */
 137 
 138 int fpm_env_init_child(struct fpm_worker_pool_s *wp) /* {{{ */
 139 {
 140         struct key_value_s *kv;
 141         char *title;
 142         spprintf(&title, 0, "pool %s", wp->config->name);
 143         fpm_env_setproctitle(title);
 144         efree(title);
 145 
 146         if (wp->config->clear_env) {
 147                 clearenv();
 148         }
 149 
 150         for (kv = wp->config->env; kv; kv = kv->next) {
 151                 setenv(kv->key, kv->value, 1);
 152         }
 153 
 154         if (wp->user) {
 155                 setenv("USER", wp->user, 1);
 156         }
 157 
 158         if (wp->home) {
 159                 setenv("HOME", wp->home, 1);
 160         }
 161 
 162         return 0;
 163 }
 164 /* }}} */
 165 
 166 static int fpm_env_conf_wp(struct fpm_worker_pool_s *wp) /* {{{ */
 167 {
 168         struct key_value_s *kv;
 169 
 170         for (kv = wp->config->env; kv; kv = kv->next) {
 171                 if (*kv->value == '$') {
 172                         char *value = getenv(kv->value + 1);
 173 
 174                         if (!value) {
 175                                 value = "";
 176                         }
 177 
 178                         free(kv->value);
 179                         kv->value = strdup(value);
 180                 }
 181 
 182                 /* autodetected values should be removed
 183                         if these vars specified in config */
 184                 if (!strcmp(kv->key, "USER")) {
 185                         free(wp->user);
 186                         wp->user = 0;
 187                 }
 188 
 189                 if (!strcmp(kv->key, "HOME")) {
 190                         free(wp->home);
 191                         wp->home = 0;
 192                 }
 193         }
 194 
 195         return 0;
 196 }
 197 /* }}} */
 198 
 199 int fpm_env_init_main() /* {{{ */
 200 {
 201         struct fpm_worker_pool_s *wp;
 202         int i;
 203         char *first = NULL;
 204         char *last = NULL;
 205         char *title;
 206 
 207         for (wp = fpm_worker_all_pools; wp; wp = wp->next) {
 208                 if (0 > fpm_env_conf_wp(wp)) {
 209                         return -1;
 210                 }
 211         }
 212 #ifndef HAVE_SETPROCTITLE
 213 #ifdef __linux__
 214         /*
 215          * This piece of code has been inspirated from nginx and pureftpd code, which
 216          * are under BSD licence.
 217          *
 218          * To change the process title in Linux we have to set argv[1] to NULL
 219          * and to copy the title to the same place where the argv[0] points to.
 220          * However, argv[0] may be too small to hold a new title.  Fortunately, Linux
 221          * store argv[] and environ[] one after another.  So we should ensure that is
 222          * the continuous memory and then we allocate the new memory for environ[]
 223          * and copy it.  After this we could use the memory starting from argv[0] for
 224          * our process title.
 225          */
 226 
 227         for (i = 0; i < fpm_globals.argc; i++) {
 228                 if (first == NULL) {
 229                         first = fpm_globals.argv[i];
 230                 }
 231                 if (last == NULL || fpm_globals.argv[i] == last + 1) {
 232                         last = fpm_globals.argv[i] + strlen(fpm_globals.argv[i]);
 233                 }
 234         }
 235         if (environ) {
 236                 for (i = 0; environ[i]; i++) {
 237                         if (first == NULL) {
 238                                 first = environ[i];
 239                         }
 240                         if (last == NULL || environ[i] == last + 1) {
 241                                 last = environ[i] + strlen(environ[i]);
 242                         }
 243                 }
 244         }
 245         if (first == NULL || last == NULL) {
 246                 return 0;
 247         }
 248 
 249         fpm_env_argv_len = last - first;
 250         fpm_env_argv = fpm_globals.argv;
 251         if (environ != NULL) {
 252                 char **new_environ;
 253                 unsigned int env_nb = 0U;
 254 
 255                 while (environ[env_nb]) {
 256                         env_nb++;
 257                 }
 258 
 259                 if ((new_environ = malloc((1U + env_nb) * sizeof (char *))) == NULL) {
 260                         return -1;
 261                 }
 262                 new_environ[env_nb] = NULL;
 263                 while (env_nb > 0U) {
 264                         env_nb--;
 265                         new_environ[env_nb] = strdup(environ[env_nb]);
 266                 }
 267                 environ = new_environ;
 268         }
 269 #endif
 270 #endif
 271 
 272         spprintf(&title, 0, "master process (%s)", fpm_globals.config);
 273         fpm_env_setproctitle(title);
 274         efree(title);
 275         return 0;
 276 }
 277 /* }}} */
 278 

/* [<][>][^][v][top][bottom][index][help] */