source: trunk/drmaa_utils/drmaa_utils/environ.c @ 1

Revision 1, 5.2 KB checked in by mmamonski, 13 years ago (diff)

Torque/PBS DRMAA initial commit

Line 
1/* $Id: environ.c 2 2009-10-12 09:51:22Z mamonski $ */
2/*
3 * FedStage DRMAA utilities library
4 * Copyright (C) 2006-2008  FedStage Systems
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <string.h>
21#include <stdlib.h>
22
23#include <drmaa_utils/common.h>
24#include <drmaa_utils/environ.h>
25#include <drmaa_utils/lookup3.h>
26
27#ifndef lint
28static char rcsid[]
29#       ifdef __GNUC__
30                __attribute__ ((unused))
31#       endif
32        = "$Id: environ.c 2 2009-10-12 09:51:22Z mamonski $";
33#endif
34
35
36static void
37fsd_environ_destroy( fsd_environ_t *self )
38{
39        unsigned i;
40        fsd_environ_item_t *j;
41        if( self->_table )
42         {
43                for( i = 0;  i < self->_table_size;  i++ )
44                        for( j = self->_table[i];  j != NULL; )
45                         {
46                                fsd_environ_item_t *to_delete = j;
47                                j = j->next;
48                                fsd_free( to_delete->name );
49                                fsd_free( to_delete->value );
50                                fsd_free( to_delete );
51                         }
52                fsd_free( self->_table );
53         }
54        fsd_free( self );
55}
56
57static const char *
58fsd_environ_get( fsd_environ_t *self, const char *name )
59{
60        uint32_t hash;
61        const fsd_environ_item_t *i;
62        hash = hashstr( name, strlen(name), 0 );
63        hash &= self->_table_size - 1;
64        for( i = self->_table[hash];  i != NULL;  i = i->next )
65                if( strcmp( i->name, name ) == 0 )
66                        return i->value;
67        return NULL;
68}
69
70static void
71fsd_environ_set( fsd_environ_t *self, char *name, char *value )
72{
73        uint32_t hash;
74        fsd_environ_item_t *i;
75        fsd_environ_item_t *item = NULL;
76        bool replaced = false;
77
78        TRY
79         {
80                hash = hashstr( name, strlen(name), 0 );
81                hash &= self->_table_size - 1;
82                for( i = self->_table[hash];  i != NULL;  i = i->next )
83                 {
84                        if( strcmp( i->name, name ) == 0 )
85                         {
86                                fsd_free( i->value );
87                                i->value = value;
88                                replaced = true;
89                                break;
90                         }
91                 }
92
93                if( !replaced )
94                 {
95                        fsd_malloc( item, fsd_environ_item_t );
96                        item->next = self->_table[hash];
97                        item->name = name;
98                        item->value = value;
99                        self->_table[hash] = item;
100                 }
101         }
102        EXCEPT_DEFAULT
103         {
104                fsd_free( name );
105                fsd_free( value );
106                fsd_exc_reraise();
107         }
108        END_TRY
109}
110
111static void
112fsd_environ_update( fsd_environ_t *self, const char *const envp[] )
113{
114        const char *const *i;
115        for( i = envp;  *i;  i++ )
116         {
117                const char *eq;
118                char *volatile name = NULL;
119                char *volatile value = NULL;
120                eq = strchr( *i, '=' );
121                if( eq == NULL )
122                        fsd_exc_raise_code( FSD_ERRNO_INVALID_VALUE_FORMAT );
123                name = fsd_strndup( *i, eq-*i );
124                TRY
125                 { value = fsd_strdup( eq+1 ); }
126                EXCEPT_DEFAULT
127                 { fsd_free(name); fsd_exc_reraise(); }
128                END_TRY
129                self->set( self, name, value );
130         }
131}
132
133static char **
134fsd_environ_list( fsd_environ_t *self )
135{
136        uint32_t i;
137        const fsd_environ_item_t *j;
138        char **volatile result = NULL;
139        unsigned items = 0;
140
141        TRY
142         {
143                for( i = 0;  i < self->_table_size;  i++ )
144                        for( j = self->_table[i];  j != NULL;  j = j->next )
145                         {
146                                items++;
147                                fsd_realloc( result, items+1, char* );
148                                result[items] = NULL;
149                                result[items-1] = fsd_asprintf( "%s=%s", j->name, j->value );
150                         }
151         }
152        EXCEPT_DEFAULT
153         {
154                fsd_free_vector( result );
155                fsd_exc_reraise();
156         }
157        END_TRY
158
159        i = 0;
160        while (result[i])
161         {
162                fsd_log_debug(("enc[%d]=%s",i, result[i]));
163                i++;
164         }
165
166        return result;
167}
168
169static fsd_environ_t *
170fsd_environ_apply( fsd_environ_t *self )
171{
172        uint32_t i;
173        const fsd_environ_item_t *j;
174        fsd_environ_t *volatile saved_state =NULL;
175        TRY
176         {
177                saved_state = fsd_environ_new( NULL );
178                for( i = 0;  i < self->_table_size;  i++ )
179                        for( j = self->_table[i];  j != NULL;  j = j->next )
180                         {
181                                const char *value = getenv( j->name );
182                                if( value )
183                                        saved_state->set( saved_state,
184                                                        fsd_strdup(j->name), fsd_strdup(value) );
185                                setenv( j->name, j->value, 1 );
186                         }
187         }
188        EXCEPT_DEFAULT
189         {
190                if( saved_state )
191                        saved_state->destroy( saved_state );
192                fsd_exc_reraise();
193         }
194        END_TRY
195        return saved_state;
196}
197
198static void
199fsd_environ_restore( fsd_environ_t *self, fsd_environ_t *saved_state )
200{
201        uint32_t i;
202        const fsd_environ_item_t *j;
203        for( i = 0;  i < self->_table_size;  i++ )
204                for( j = self->_table[i];  j != NULL;  j = j->next )
205                 {
206                        const char *value = saved_state->get( saved_state, j->name );
207                        if( value )
208                                setenv( j->name, value, 1 );
209                        else
210                                unsetenv( j->name );
211                 }
212}
213
214fsd_environ_t *
215fsd_environ_new( const char *const envp[] )
216{
217        fsd_environ_t *volatile self = NULL;
218        TRY
219         {
220                fsd_malloc( self, fsd_environ_t );
221                self->destroy = fsd_environ_destroy;
222                self->get = fsd_environ_get;
223                self->set = fsd_environ_set;
224                self->update = fsd_environ_update;
225                self->list = fsd_environ_list;
226                self->apply = fsd_environ_apply;
227                self->restore = fsd_environ_restore;
228                self->_table_size = 256;
229                fsd_calloc( self->_table, self->_table_size, fsd_environ_item_t* );
230                if( envp )
231                        self->update( self, envp );
232         }
233        EXCEPT_DEFAULT
234         {
235                if( self )
236                        self->destroy( self );
237         }
238        END_TRY
239        return self;
240}
241
Note: See TracBrowser for help on using the repository browser.