Annotation of embedaddon/tmux/environ.c, revision 1.1

1.1     ! misho       1: /* $OpenBSD$ */
        !             2: 
        !             3: /*
        !             4:  * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
        !             5:  *
        !             6:  * Permission to use, copy, modify, and distribute this software for any
        !             7:  * purpose with or without fee is hereby granted, provided that the above
        !             8:  * copyright notice and this permission notice appear in all copies.
        !             9:  *
        !            10:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
        !            11:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
        !            12:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
        !            13:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
        !            14:  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
        !            15:  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
        !            16:  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
        !            17:  */
        !            18: 
        !            19: #include <sys/types.h>
        !            20: 
        !            21: #include <stdlib.h>
        !            22: #include <string.h>
        !            23: #include <unistd.h>
        !            24: 
        !            25: #include "tmux.h"
        !            26: 
        !            27: /*
        !            28:  * Environment - manipulate a set of environment variables.
        !            29:  */
        !            30: 
        !            31: RB_HEAD(environ, environ_entry);
        !            32: static int environ_cmp(struct environ_entry *, struct environ_entry *);
        !            33: RB_GENERATE_STATIC(environ, environ_entry, entry, environ_cmp);
        !            34: 
        !            35: static int
        !            36: environ_cmp(struct environ_entry *envent1, struct environ_entry *envent2)
        !            37: {
        !            38:        return (strcmp(envent1->name, envent2->name));
        !            39: }
        !            40: 
        !            41: /* Initialise the environment. */
        !            42: struct environ *
        !            43: environ_create(void)
        !            44: {
        !            45:        struct environ  *env;
        !            46: 
        !            47:        env = xcalloc(1, sizeof *env);
        !            48:        RB_INIT(env);
        !            49: 
        !            50:        return (env);
        !            51: }
        !            52: 
        !            53: /* Free an environment. */
        !            54: void
        !            55: environ_free(struct environ *env)
        !            56: {
        !            57:        struct environ_entry    *envent, *envent1;
        !            58: 
        !            59:        RB_FOREACH_SAFE(envent, environ, env, envent1) {
        !            60:                RB_REMOVE(environ, env, envent);
        !            61:                free(envent->name);
        !            62:                free(envent->value);
        !            63:                free(envent);
        !            64:        }
        !            65:        free(env);
        !            66: }
        !            67: 
        !            68: struct environ_entry *
        !            69: environ_first(struct environ *env)
        !            70: {
        !            71:        return (RB_MIN(environ, env));
        !            72: }
        !            73: 
        !            74: struct environ_entry *
        !            75: environ_next(struct environ_entry *envent)
        !            76: {
        !            77:        return (RB_NEXT(environ, env, envent));
        !            78: }
        !            79: 
        !            80: /* Copy one environment into another. */
        !            81: void
        !            82: environ_copy(struct environ *srcenv, struct environ *dstenv)
        !            83: {
        !            84:        struct environ_entry    *envent;
        !            85: 
        !            86:        RB_FOREACH(envent, environ, srcenv) {
        !            87:                if (envent->value == NULL)
        !            88:                        environ_clear(dstenv, envent->name);
        !            89:                else
        !            90:                        environ_set(dstenv, envent->name, "%s", envent->value);
        !            91:        }
        !            92: }
        !            93: 
        !            94: /* Find an environment variable. */
        !            95: struct environ_entry *
        !            96: environ_find(struct environ *env, const char *name)
        !            97: {
        !            98:        struct environ_entry    envent;
        !            99: 
        !           100:        envent.name = (char *) name;
        !           101:        return (RB_FIND(environ, env, &envent));
        !           102: }
        !           103: 
        !           104: /* Set an environment variable. */
        !           105: void
        !           106: environ_set(struct environ *env, const char *name, const char *fmt, ...)
        !           107: {
        !           108:        struct environ_entry    *envent;
        !           109:        va_list                  ap;
        !           110: 
        !           111:        va_start(ap, fmt);
        !           112:        if ((envent = environ_find(env, name)) != NULL) {
        !           113:                free(envent->value);
        !           114:                xvasprintf(&envent->value, fmt, ap);
        !           115:        } else {
        !           116:                envent = xmalloc(sizeof *envent);
        !           117:                envent->name = xstrdup(name);
        !           118:                xvasprintf(&envent->value, fmt, ap);
        !           119:                RB_INSERT(environ, env, envent);
        !           120:        }
        !           121:        va_end(ap);
        !           122: }
        !           123: 
        !           124: /* Clear an environment variable. */
        !           125: void
        !           126: environ_clear(struct environ *env, const char *name)
        !           127: {
        !           128:        struct environ_entry    *envent;
        !           129: 
        !           130:        if ((envent = environ_find(env, name)) != NULL) {
        !           131:                free(envent->value);
        !           132:                envent->value = NULL;
        !           133:        } else {
        !           134:                envent = xmalloc(sizeof *envent);
        !           135:                envent->name = xstrdup(name);
        !           136:                envent->value = NULL;
        !           137:                RB_INSERT(environ, env, envent);
        !           138:        }
        !           139: }
        !           140: 
        !           141: /* Set an environment variable from a NAME=VALUE string. */
        !           142: void
        !           143: environ_put(struct environ *env, const char *var)
        !           144: {
        !           145:        char    *name, *value;
        !           146: 
        !           147:        value = strchr(var, '=');
        !           148:        if (value == NULL)
        !           149:                return;
        !           150:        value++;
        !           151: 
        !           152:        name = xstrdup(var);
        !           153:        name[strcspn(name, "=")] = '\0';
        !           154: 
        !           155:        environ_set(env, name, "%s", value);
        !           156:        free(name);
        !           157: }
        !           158: 
        !           159: /* Unset an environment variable. */
        !           160: void
        !           161: environ_unset(struct environ *env, const char *name)
        !           162: {
        !           163:        struct environ_entry    *envent;
        !           164: 
        !           165:        if ((envent = environ_find(env, name)) == NULL)
        !           166:                return;
        !           167:        RB_REMOVE(environ, env, envent);
        !           168:        free(envent->name);
        !           169:        free(envent->value);
        !           170:        free(envent);
        !           171: }
        !           172: 
        !           173: /* Copy variables from a destination into a source * environment. */
        !           174: void
        !           175: environ_update(struct options *oo, struct environ *src, struct environ *dst)
        !           176: {
        !           177:        struct environ_entry    *envent;
        !           178:        struct options_entry    *o;
        !           179:        u_int                    size, idx;
        !           180:        const char              *value;
        !           181: 
        !           182:        o = options_get(oo, "update-environment");
        !           183:        if (o == NULL || options_array_size(o, &size) == -1)
        !           184:                return;
        !           185:        for (idx = 0; idx < size; idx++) {
        !           186:                value = options_array_get(o, idx);
        !           187:                if (value == NULL)
        !           188:                        continue;
        !           189:                if ((envent = environ_find(src, value)) == NULL)
        !           190:                        environ_clear(dst, value);
        !           191:                else
        !           192:                        environ_set(dst, envent->name, "%s", envent->value);
        !           193:        }
        !           194: }
        !           195: 
        !           196: /* Push environment into the real environment - use after fork(). */
        !           197: void
        !           198: environ_push(struct environ *env)
        !           199: {
        !           200:        struct environ_entry    *envent;
        !           201: 
        !           202:        environ = xcalloc(1, sizeof *environ);
        !           203:        RB_FOREACH(envent, environ, env) {
        !           204:                if (envent->value != NULL && *envent->name != '\0')
        !           205:                        setenv(envent->name, envent->value, 1);
        !           206:        }
        !           207: }
        !           208: 
        !           209: /* Log the environment. */
        !           210: void
        !           211: environ_log(struct environ *env, const char *prefix)
        !           212: {
        !           213:        struct environ_entry    *envent;
        !           214: 
        !           215:        RB_FOREACH(envent, environ, env) {
        !           216:                if (envent->value != NULL && *envent->name != '\0') {
        !           217:                        log_debug("%s%s=%s", prefix, envent->name,
        !           218:                            envent->value);
        !           219:                }
        !           220:        }
        !           221: }
        !           222: 
        !           223: /* Create initial environment for new child. */
        !           224: struct environ *
        !           225: environ_for_session(struct session *s)
        !           226: {
        !           227:        struct environ  *env;
        !           228:        const char      *value;
        !           229:        int              idx;
        !           230: 
        !           231:        env = environ_create();
        !           232:        environ_copy(global_environ, env);
        !           233:        if (s != NULL)
        !           234:                environ_copy(s->environ, env);
        !           235: 
        !           236:        value = options_get_string(global_options, "default-terminal");
        !           237:        environ_set(env, "TERM", "%s", value);
        !           238: 
        !           239:        if (s != NULL)
        !           240:                idx = s->id;
        !           241:        else
        !           242:                idx = -1;
        !           243:        environ_set(env, "TMUX", "%s,%ld,%d", socket_path, (long)getpid(), idx);
        !           244: 
        !           245:        return (env);
        !           246: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>