Back to index

php5  5.3.10
fpm_env.c
Go to the documentation of this file.
00001 
00002        /* $Id: fpm_env.c,v 1.15 2008/09/18 23:19:59 anight Exp $ */
00003        /* (c) 2007,2008 Andrei Nigmatulin */
00004 
00005 #include "fpm_config.h"
00006 
00007 #ifdef HAVE_ALLOCA_H
00008 #include <alloca.h>
00009 #endif
00010 #include <stdio.h>
00011 #include <stdlib.h>
00012 #include <string.h>
00013 
00014 #include "fpm_env.h"
00015 #include "fpm.h"
00016 
00017 #ifndef HAVE_SETPROCTITLE
00018 #ifdef __linux__
00019 static char **fpm_env_argv = NULL;
00020 static size_t fpm_env_argv_len = 0;
00021 #endif
00022 #endif
00023 
00024 #ifndef HAVE_SETENV
00025 # ifdef (__sparc__ || __sparc)
00026 int setenv(char *name, char *value, int clobber) /* {{{ */
00027 {
00028        char   *malloc();
00029        char   *getenv();
00030        char   *cp;
00031 
00032        if (clobber == 0 && getenv(name) != 0) {
00033               return 0;
00034        }
00035        
00036        if ((cp = malloc(strlen(name) + strlen(value) + 2)) == 0) {
00037               return 1;
00038        }
00039        sprintf(cp, "%s=%s", name, value);
00040        return putenv(cp);
00041 }
00042 /* }}} */
00043 # else
00044 int setenv(char *name, char *value, int overwrite) /* {{{ */
00045 {
00046        int name_len = strlen(name);
00047        int value_len = strlen(value);
00048        char *var = alloca(name_len + 1 + value_len + 1);
00049 
00050        memcpy(var, name, name_len);
00051 
00052        var[name_len] = '=';
00053 
00054        memcpy(var + name_len + 1, value, value_len);
00055 
00056        var[name_len + 1 + value_len] = '\0';
00057 
00058        return putenv(var);
00059 }
00060 /* }}} */
00061 # endif
00062 #endif
00063 
00064 #ifndef HAVE_CLEARENV
00065 void clearenv() /* {{{ */
00066 {
00067        char **envp;
00068        char *s;
00069 
00070        /* this algo is the only one known to me
00071               that works well on all systems */
00072        while (*(envp = environ)) {
00073               char *eq = strchr(*envp, '=');
00074 
00075               s = strdup(*envp);
00076 
00077               if (eq) s[eq - *envp] = '\0';
00078 
00079               unsetenv(s);
00080               free(s);
00081        }
00082 
00083 }
00084 /* }}} */
00085 #endif
00086 
00087 #ifndef HAVE_UNSETENV
00088 void unsetenv(const char *name) /* {{{ */
00089 {
00090        if(getenv(name) != NULL) {
00091               int ct = 0;
00092               int del = 0;
00093 
00094               while(environ[ct] != NULL) {
00095                      if (nvmatch(name, environ[ct]) != 0) del=ct; /* <--- WTF?! */
00096                      { ct++; } /* <--- WTF?! */
00097               }
00098               /* isn't needed free here?? */
00099               environ[del] = environ[ct-1];
00100               environ[ct-1] = NULL;
00101        }
00102 }
00103 /* }}} */
00104 
00105 static char * nvmatch(char *s1, char *s2) /* {{{ */
00106 {
00107        while(*s1 == *s2++)
00108        {
00109               if(*s1++ == '=') { 
00110                      return s2;
00111               }
00112        }
00113        if(*s1 == '\0' && *(s2-1) == '=') { 
00114               return s2;
00115        }
00116        return NULL;
00117 }
00118 /* }}} */
00119 #endif
00120 
00121 void fpm_env_setproctitle(char *title) /* {{{ */
00122 {
00123 #ifdef HAVE_SETPROCTITLE
00124        setproctitle("%s", title);
00125 #else
00126 #ifdef __linux__
00127        if (fpm_env_argv != NULL && fpm_env_argv_len > strlen(SETPROCTITLE_PREFIX) + 3) {
00128               memset(fpm_env_argv[0], 0, fpm_env_argv_len);
00129               strncpy(fpm_env_argv[0], SETPROCTITLE_PREFIX, fpm_env_argv_len - 2);
00130               strncpy(fpm_env_argv[0] + strlen(SETPROCTITLE_PREFIX), title, fpm_env_argv_len - strlen(SETPROCTITLE_PREFIX) - 2);
00131               fpm_env_argv[1] = NULL;
00132        }
00133 #endif
00134 #endif
00135 }
00136 /* }}} */
00137 
00138 int fpm_env_init_child(struct fpm_worker_pool_s *wp) /* {{{ */
00139 {
00140        struct key_value_s *kv;
00141        char *title;
00142        spprintf(&title, 0, "pool %s", wp->config->name);
00143        fpm_env_setproctitle(title);
00144        efree(title);
00145 
00146        clearenv();
00147 
00148        for (kv = wp->config->env; kv; kv = kv->next) {
00149               setenv(kv->key, kv->value, 1);
00150        }
00151 
00152        if (wp->user) {
00153               setenv("USER", wp->user, 1);
00154        }
00155 
00156        if (wp->home) {
00157               setenv("HOME", wp->home, 1);
00158        }
00159 
00160        return 0;
00161 }
00162 /* }}} */
00163 
00164 static int fpm_env_conf_wp(struct fpm_worker_pool_s *wp) /* {{{ */
00165 {
00166        struct key_value_s *kv;
00167 
00168        for (kv = wp->config->env; kv; kv = kv->next) {
00169               if (*kv->value == '$') {
00170                      char *value = getenv(kv->value + 1);
00171 
00172                      if (!value) {
00173                             value = "";
00174                      }
00175 
00176                      free(kv->value);
00177                      kv->value = strdup(value);
00178               }
00179 
00180               /* autodetected values should be removed
00181                      if these vars specified in config */
00182               if (!strcmp(kv->key, "USER")) {
00183                      free(wp->user);
00184                      wp->user = 0;
00185               }
00186 
00187               if (!strcmp(kv->key, "HOME")) {
00188                      free(wp->home);
00189                      wp->home = 0;
00190               }
00191        }
00192 
00193        return 0;
00194 }
00195 /* }}} */
00196 
00197 int fpm_env_init_main() /* {{{ */
00198 {
00199        struct fpm_worker_pool_s *wp;
00200        int i;
00201        char *first = NULL;
00202        char *last = NULL;
00203        char *title;
00204 
00205        for (wp = fpm_worker_all_pools; wp; wp = wp->next) {
00206               if (0 > fpm_env_conf_wp(wp)) {
00207                      return -1;
00208               }
00209        }
00210 #ifndef HAVE_SETPROCTITLE
00211 #ifdef __linux__
00212        /*
00213         * This piece of code has been inspirated from nginx and pureftpd code, whic
00214         * are under BSD licence.
00215         *
00216         * To change the process title in Linux we have to set argv[1] to NULL
00217         * and to copy the title to the same place where the argv[0] points to.
00218         * However, argv[0] may be too small to hold a new title.  Fortunately, Linux
00219         * store argv[] and environ[] one after another.  So we should ensure that is
00220         * the continuous memory and then we allocate the new memory for environ[]
00221         * and copy it.  After this we could use the memory starting from argv[0] for
00222         * our process title.
00223         */
00224 
00225        for (i = 0; i < fpm_globals.argc; i++) {
00226               if (first == NULL) {
00227                      first = fpm_globals.argv[i];
00228               }
00229               if (last == NULL || fpm_globals.argv[i] == last + 1) {
00230                      last = fpm_globals.argv[i] + strlen(fpm_globals.argv[i]);
00231               }
00232        }
00233        if (environ) {
00234               for (i = 0; environ[i]; i++) {
00235                      if (first == NULL) {
00236                             first = environ[i];
00237                      }
00238                      if (last == NULL || environ[i] == last + 1) {
00239                             last = environ[i] + strlen(environ[i]);
00240                      }
00241               }
00242        }
00243        if (first == NULL || last == NULL) {
00244               return 0;
00245        }
00246 
00247        fpm_env_argv_len = last - first;
00248        fpm_env_argv = fpm_globals.argv;
00249        if (environ != NULL) {
00250               char **new_environ;
00251               unsigned int env_nb = 0U;
00252 
00253               while (environ[env_nb]) {
00254                      env_nb++;
00255               }
00256 
00257               if ((new_environ = malloc((1U + env_nb) * sizeof (char *))) == NULL) {
00258                      return -1;
00259               }
00260               new_environ[env_nb] = NULL;
00261               while (env_nb > 0U) {
00262                      env_nb--;
00263                      new_environ[env_nb] = strdup(environ[env_nb]);
00264               }
00265               environ = new_environ;
00266        }
00267 #endif
00268 #endif
00269 
00270        spprintf(&title, 0, "master process (%s)", fpm_globals.config);
00271        fpm_env_setproctitle(title); 
00272        efree(title);
00273        return 0;
00274 }
00275 /* }}} */
00276