mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-26 12:53:13 +00:00
Make fish store universal variables locally if fishd can't be started - local changes are lost of the fishd connection is restored
darcs-hash:20061115123447-ac50b-bf17c55079e1196205cc3a4fd0ca22d9f539836c.gz
This commit is contained in:
parent
d00bc973fe
commit
3b2670532a
3 changed files with 156 additions and 45 deletions
|
@ -70,6 +70,11 @@ static int barrier_reply = 0;
|
||||||
|
|
||||||
void env_universal_barrier();
|
void env_universal_barrier();
|
||||||
|
|
||||||
|
static int is_dead()
|
||||||
|
{
|
||||||
|
return env_universal_server.fd < 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get a socket for reading from the server
|
Get a socket for reading from the server
|
||||||
|
@ -140,7 +145,7 @@ static int get_socket( int fork_ok )
|
||||||
return get_socket( 0 );
|
return get_socket( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
debug( 2, L"Could not connect to socket %d, already tried manual restart (or no command supplied), giving up", s );
|
debug( 1, L"Could not connect to universal variable server, already tried manual restart (or no command supplied). You will not be able to share variable values between fish sessions. Is fish properly installed?" );
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,7 +156,7 @@ static int get_socket( int fork_ok )
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
debug( 3, L"Connected to fd %d", s );
|
debug( 3, L"Connected to fd %d", s );
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
|
@ -198,6 +203,31 @@ static void check_connection()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Remove all universal variables.
|
||||||
|
*/
|
||||||
|
static void env_universal_remove_all()
|
||||||
|
{
|
||||||
|
array_list_t lst;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
al_init( &lst );
|
||||||
|
|
||||||
|
env_universal_common_get_names( &lst,
|
||||||
|
1,
|
||||||
|
1 );
|
||||||
|
|
||||||
|
for( i=0; i<al_get_count( &lst ); i++ )
|
||||||
|
{
|
||||||
|
wchar_t *key = (wchar_t *)al_get( &lst, i );
|
||||||
|
env_universal_common_remove( key );
|
||||||
|
}
|
||||||
|
|
||||||
|
al_destroy( &lst );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Try to establish a new connection to fishd. If successfull, end
|
Try to establish a new connection to fishd. If successfull, end
|
||||||
with call to env_universal_barrier(), to make sure everything is in
|
with call to env_universal_barrier(), to make sure everything is in
|
||||||
|
@ -216,6 +246,7 @@ static void reconnect()
|
||||||
init = 1;
|
init = 1;
|
||||||
if( env_universal_server.fd >= 0 )
|
if( env_universal_server.fd >= 0 )
|
||||||
{
|
{
|
||||||
|
env_universal_remove_all();
|
||||||
env_universal_barrier();
|
env_universal_barrier();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -317,7 +348,7 @@ void env_universal_barrier()
|
||||||
message_t *msg;
|
message_t *msg;
|
||||||
fd_set fds;
|
fd_set fds;
|
||||||
|
|
||||||
if( !init || ( env_universal_server.fd == -1 ))
|
if( !init || is_dead() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
barrier_reply = 0;
|
barrier_reply = 0;
|
||||||
|
@ -384,20 +415,27 @@ void env_universal_set( const wchar_t *name, const wchar_t *value, int export )
|
||||||
CHECK( name, );
|
CHECK( name, );
|
||||||
|
|
||||||
debug( 3, L"env_universal_set( \"%ls\", \"%ls\" )", name, value );
|
debug( 3, L"env_universal_set( \"%ls\", \"%ls\" )", name, value );
|
||||||
|
|
||||||
msg = create_message( export?SET_EXPORT:SET,
|
|
||||||
name,
|
|
||||||
value);
|
|
||||||
|
|
||||||
if( !msg )
|
if( is_dead() )
|
||||||
{
|
{
|
||||||
debug( 1, L"Could not create universal variable message" );
|
env_universal_common_set( name, value, export );
|
||||||
return;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
msg = create_message( export?SET_EXPORT:SET,
|
||||||
|
name,
|
||||||
|
value);
|
||||||
|
|
||||||
|
if( !msg )
|
||||||
|
{
|
||||||
|
debug( 1, L"Could not create universal variable message" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg->count=1;
|
||||||
|
q_put( &env_universal_server.unsent, msg );
|
||||||
|
env_universal_barrier();
|
||||||
}
|
}
|
||||||
|
|
||||||
msg->count=1;
|
|
||||||
q_put( &env_universal_server.unsent, msg );
|
|
||||||
env_universal_barrier();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int env_universal_remove( const wchar_t *name )
|
int env_universal_remove( const wchar_t *name )
|
||||||
|
@ -411,16 +449,22 @@ int env_universal_remove( const wchar_t *name )
|
||||||
CHECK( name, 1 );
|
CHECK( name, 1 );
|
||||||
|
|
||||||
res = !env_universal_common_get( name );
|
res = !env_universal_common_get( name );
|
||||||
|
|
||||||
debug( 3,
|
debug( 3,
|
||||||
L"env_universal_remove( \"%ls\" )",
|
L"env_universal_remove( \"%ls\" )",
|
||||||
name );
|
name );
|
||||||
|
|
||||||
msg= create_message( ERASE, name, 0);
|
if( is_dead() )
|
||||||
msg->count=1;
|
{
|
||||||
q_put( &env_universal_server.unsent, msg );
|
env_universal_common_remove( name );
|
||||||
env_universal_barrier();
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
msg= create_message( ERASE, name, 0);
|
||||||
|
msg->count=1;
|
||||||
|
q_put( &env_universal_server.unsent, msg );
|
||||||
|
env_universal_barrier();
|
||||||
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -430,6 +474,8 @@ void env_universal_get_names( array_list_t *l,
|
||||||
{
|
{
|
||||||
if( !init )
|
if( !init )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
CHECK( l, );
|
||||||
|
|
||||||
env_universal_common_get_names( l,
|
env_universal_common_get_names( l,
|
||||||
show_exported,
|
show_exported,
|
||||||
|
|
|
@ -423,7 +423,7 @@ void read_message( connection_t *src )
|
||||||
/**
|
/**
|
||||||
Remove variable with specified name
|
Remove variable with specified name
|
||||||
*/
|
*/
|
||||||
static void remove_entry( wchar_t *name )
|
void env_universal_common_remove( const wchar_t *name )
|
||||||
{
|
{
|
||||||
void *k, *v;
|
void *k, *v;
|
||||||
hash_remove( &env_universal_var,
|
hash_remove( &env_universal_var,
|
||||||
|
@ -449,6 +449,34 @@ static int match( const wchar_t *msg, const wchar_t *cmd )
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void env_universal_common_set( const wchar_t *key, const wchar_t *val, int export )
|
||||||
|
{
|
||||||
|
var_uni_entry_t *entry;
|
||||||
|
wchar_t *name;
|
||||||
|
|
||||||
|
CHECK( key, );
|
||||||
|
CHECK( val, );
|
||||||
|
|
||||||
|
entry = malloc( sizeof(var_uni_entry_t) + sizeof(wchar_t)*(wcslen(val)+1) );
|
||||||
|
name = wcsdup(key);
|
||||||
|
|
||||||
|
if( !entry || !name )
|
||||||
|
DIE_MEM();
|
||||||
|
|
||||||
|
entry->export=export;
|
||||||
|
|
||||||
|
wcscpy( entry->val, val );
|
||||||
|
env_universal_common_remove( name );
|
||||||
|
|
||||||
|
hash_put( &env_universal_var, name, entry );
|
||||||
|
|
||||||
|
if( callback )
|
||||||
|
{
|
||||||
|
callback( export?SET_EXPORT:SET, name, val );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Parse message msg
|
Parse message msg
|
||||||
*/
|
*/
|
||||||
|
@ -462,7 +490,7 @@ static void parse_message( wchar_t *msg,
|
||||||
|
|
||||||
if( match( msg, SET_STR ) || match( msg, SET_EXPORT_STR ))
|
if( match( msg, SET_STR ) || match( msg, SET_EXPORT_STR ))
|
||||||
{
|
{
|
||||||
wchar_t *name, *val, *tmp;
|
wchar_t *name, *tmp;
|
||||||
int export = match( msg, SET_EXPORT_STR );
|
int export = match( msg, SET_EXPORT_STR );
|
||||||
|
|
||||||
name = msg+(export?wcslen(SET_EXPORT_STR):wcslen(SET_STR));
|
name = msg+(export?wcslen(SET_EXPORT_STR):wcslen(SET_STR));
|
||||||
|
@ -472,31 +500,20 @@ static void parse_message( wchar_t *msg,
|
||||||
tmp = wcschr( name, L':' );
|
tmp = wcschr( name, L':' );
|
||||||
if( tmp )
|
if( tmp )
|
||||||
{
|
{
|
||||||
wchar_t *key =malloc( sizeof( wchar_t)*(tmp-name+1));
|
wchar_t *key;
|
||||||
|
wchar_t *val;
|
||||||
|
|
||||||
|
key = malloc( sizeof( wchar_t)*(tmp-name+1));
|
||||||
memcpy( key, name, sizeof( wchar_t)*(tmp-name));
|
memcpy( key, name, sizeof( wchar_t)*(tmp-name));
|
||||||
key[tmp-name]=0;
|
key[tmp-name]=0;
|
||||||
|
|
||||||
val = tmp+1;
|
val = tmp+1;
|
||||||
|
|
||||||
|
|
||||||
val = unescape( val, 0 );
|
val = unescape( val, 0 );
|
||||||
|
|
||||||
var_uni_entry_t *entry =
|
env_universal_common_set( key, val, export );
|
||||||
malloc( sizeof(var_uni_entry_t) + sizeof(wchar_t)*(wcslen(val)+1) );
|
|
||||||
if( !entry )
|
|
||||||
DIE_MEM();
|
|
||||||
entry->export=export;
|
|
||||||
|
|
||||||
wcscpy( entry->val, val );
|
free( val );
|
||||||
remove_entry( key );
|
free( key );
|
||||||
|
|
||||||
hash_put( &env_universal_var, key, entry );
|
|
||||||
|
|
||||||
if( callback )
|
|
||||||
{
|
|
||||||
callback( export?SET_EXPORT:SET, key, val );
|
|
||||||
}
|
|
||||||
free(val );
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -522,7 +539,7 @@ static void parse_message( wchar_t *msg,
|
||||||
debug( 1, PARSE_ERR, msg );
|
debug( 1, PARSE_ERR, msg );
|
||||||
}
|
}
|
||||||
|
|
||||||
remove_entry( name );
|
env_universal_common_remove( name );
|
||||||
|
|
||||||
if( callback )
|
if( callback )
|
||||||
{
|
{
|
||||||
|
@ -853,8 +870,16 @@ void connection_destroy( connection_t *c)
|
||||||
{
|
{
|
||||||
q_destroy( &c->unsent );
|
q_destroy( &c->unsent );
|
||||||
b_destroy( &c->input );
|
b_destroy( &c->input );
|
||||||
if( close( c->fd ) )
|
|
||||||
|
/*
|
||||||
|
A connection need not always be open - we only try to close it
|
||||||
|
if it is open.
|
||||||
|
*/
|
||||||
|
if( c->fd >= 0 )
|
||||||
{
|
{
|
||||||
wperror( L"close" );
|
if( close( c->fd ) )
|
||||||
|
{
|
||||||
|
wperror( L"close" );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,19 +143,50 @@ void env_universal_common_destroy();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Add all variable names to the specified list
|
Add all variable names to the specified list
|
||||||
|
|
||||||
|
This function operate agains the local copy of all universal
|
||||||
|
variables, it does not communicate with any other process.
|
||||||
*/
|
*/
|
||||||
void env_universal_common_get_names( array_list_t *l,
|
void env_universal_common_get_names( array_list_t *l,
|
||||||
int show_exported,
|
int show_exported,
|
||||||
int show_unexported );
|
int show_unexported );
|
||||||
|
|
||||||
|
/**
|
||||||
|
Perform the specified variable assignment.
|
||||||
|
|
||||||
|
This function operate agains the local copy of all universal
|
||||||
|
variables, it does not communicate with any other process.
|
||||||
|
|
||||||
|
Do not call this function. Create a message to do it. This function
|
||||||
|
is only to be used when fishd is dead.
|
||||||
|
*/
|
||||||
|
void env_universal_common_set( const wchar_t *key, const wchar_t *val, int export );
|
||||||
|
|
||||||
|
/**
|
||||||
|
Remove the specified variable.
|
||||||
|
|
||||||
|
This function operate agains the local copy of all universal
|
||||||
|
variables, it does not communicate with any other process.
|
||||||
|
|
||||||
|
Do not call this function. Create a message to do it. This function
|
||||||
|
is only to be used when fishd is dead.
|
||||||
|
*/
|
||||||
|
void env_universal_common_remove( const wchar_t *key );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get the value of the variable with the specified name
|
Get the value of the variable with the specified name
|
||||||
|
|
||||||
|
This function operate agains the local copy of all universal
|
||||||
|
variables, it does not communicate with any other process.
|
||||||
*/
|
*/
|
||||||
wchar_t *env_universal_common_get( const wchar_t *name );
|
wchar_t *env_universal_common_get( const wchar_t *name );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get the export flag of the variable with the specified
|
Get the export flag of the variable with the specified
|
||||||
name. Returns 0 if the variable doesn't exist.
|
name. Returns 0 if the variable doesn't exist.
|
||||||
|
|
||||||
|
This function operate agains the local copy of all universal
|
||||||
|
variables, it does not communicate with any other process.
|
||||||
*/
|
*/
|
||||||
int env_universal_common_get_export( const wchar_t *name );
|
int env_universal_common_get_export( const wchar_t *name );
|
||||||
|
|
||||||
|
@ -164,8 +195,17 @@ int env_universal_common_get_export( const wchar_t *name );
|
||||||
*/
|
*/
|
||||||
void enqueue_all( connection_t *c );
|
void enqueue_all( connection_t *c );
|
||||||
|
|
||||||
|
/**
|
||||||
|
Fill in the specified connection_t struct. Use the specified file
|
||||||
|
descriptor for communication.
|
||||||
|
*/
|
||||||
void connection_init( connection_t *c, int fd );
|
void connection_init( connection_t *c, int fd );
|
||||||
|
|
||||||
|
/**
|
||||||
|
Close and destroy the specified connection struct. This frees
|
||||||
|
allstructures allocated by the connection, such as ques of unsent
|
||||||
|
messages.
|
||||||
|
*/
|
||||||
void connection_destroy( connection_t *c);
|
void connection_destroy( connection_t *c);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue