mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-26 12:53:13 +00:00
Exportable universal variables
darcs-hash:20050922201652-ac50b-f70e7607b4ace24da4020f2d432718dc335e5bdd.gz
This commit is contained in:
parent
fcdaed44d7
commit
f971e02256
19 changed files with 539 additions and 203 deletions
|
@ -328,6 +328,9 @@ tokenize: tokenize.o doc_src/tokenize.c
|
|||
tokenizer_test: tokenizer.c tokenizer.h util.o wutil.o common.o
|
||||
$(CC) ${CFLAGS} tokenizer.c util.o wutil.o common.o -D TOKENIZER_TEST $(LDFLAGS) -o $@
|
||||
|
||||
key_reader: key_reader.o input_common.o common.o env_universal.o env_universal_common.o util.o wutil.o
|
||||
$(CC) key_reader.o input_common.o common.o env_universal.o env_universal_common.o util.o wutil.o $(LDFLAGS) -o $@
|
||||
|
||||
depend:
|
||||
makedepend -fMakefile.in -Y *.c
|
||||
|
||||
|
|
|
@ -234,7 +234,7 @@ static void print_variables(int include_values, int escape, int scope)
|
|||
|
||||
for( i = 0; i < al_get_count(&names); i++ )
|
||||
{
|
||||
wchar_t *key = al_get( &names, i );
|
||||
wchar_t *key = (wchar_t *)al_get( &names, i );
|
||||
/* Why does expand_escape free its argument ?! */
|
||||
wchar_t *e_key = escape ? expand_escape(wcsdup(key), 1) : wcsdup(key);
|
||||
sb_append(sb_out, e_key);
|
||||
|
@ -283,13 +283,16 @@ int builtin_set( wchar_t **argv )
|
|||
{
|
||||
L"universal", no_argument, 0, 'U'
|
||||
} ,
|
||||
{
|
||||
L"query", no_argument, 0, 'q'
|
||||
} ,
|
||||
{
|
||||
0, 0, 0, 0
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
wchar_t short_options[] = L"xglenuU";
|
||||
wchar_t short_options[] = L"xglenuUq";
|
||||
|
||||
int argc = builtin_count_args(argv);
|
||||
|
||||
|
@ -298,7 +301,7 @@ int builtin_set( wchar_t **argv )
|
|||
*/
|
||||
int local = 0, global = 0, export = 0;
|
||||
int erase = 0, list = 0, unexport=0;
|
||||
int universal = 0;
|
||||
int universal = 0, query=0;
|
||||
|
||||
|
||||
/*
|
||||
|
@ -349,6 +352,9 @@ int builtin_set( wchar_t **argv )
|
|||
case 'U':
|
||||
universal = 1;
|
||||
break;
|
||||
case 'q':
|
||||
query = 1;
|
||||
break;
|
||||
case '?':
|
||||
return 1;
|
||||
default:
|
||||
|
@ -356,6 +362,20 @@ int builtin_set( wchar_t **argv )
|
|||
}
|
||||
}
|
||||
|
||||
if( query && (erase || list || global || local || universal || export || unexport ) )
|
||||
{
|
||||
sb_append2(sb_err,
|
||||
argv[0],
|
||||
BUILTIN_ERR_COMBO,
|
||||
L"\n",
|
||||
parser_current_line(),
|
||||
L"\n",
|
||||
0);
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* Check operation and modifiers sanity */
|
||||
if( erase && list )
|
||||
{
|
||||
|
@ -394,6 +414,22 @@ int builtin_set( wchar_t **argv )
|
|||
return 1;
|
||||
}
|
||||
|
||||
if( query )
|
||||
{
|
||||
/*
|
||||
Query mode. Return number of specified variables that do not exist.
|
||||
*/
|
||||
int i;
|
||||
for( i=woptind; i<argc; i++ )
|
||||
{
|
||||
if( env_get( argv[i] )==0 )
|
||||
retcode++;
|
||||
|
||||
}
|
||||
return retcode;
|
||||
}
|
||||
|
||||
|
||||
/* Parse destination */
|
||||
if( woptind < argc )
|
||||
{
|
||||
|
|
|
@ -882,7 +882,8 @@ g++, javac, java, gcj, lpr, doxygen, whois, find)
|
|||
version of a POSIX command
|
||||
- Yanking weird characters from clipboard prints Unicode escapes
|
||||
- Prefix string in completion display is sometimes incorrect
|
||||
|
||||
- Pressing escape when doing a token search breaks things
|
||||
- Universal variables should be exportable
|
||||
|
||||
If you think you have found a bug not described here, please send a
|
||||
report to <a href="mailto:axel@liljencrantz.se"> axel@liljencrantz.se
|
||||
|
|
|
@ -7,12 +7,13 @@ The <tt>set</tt> builtin causes fish to assign the variable <tt>VARIABLE_NAME</t
|
|||
|
||||
\subsection set-description Description
|
||||
- <tt>-e</tt> or <tt>--erase</tt> causes the specified environment variables to be erased
|
||||
- <tt>-U</tt> or <tt>--universal</tt> causes the specified environment variable to be made universal. If this option is supplied, the variable will be shared between all the current users fish instances on the current computer, and will be preserved across restarts of the shell.
|
||||
- <tt>-g</tt> or <tt>--global</tt> causes the specified environment variable to be made global. If this option is not supplied, the specified variable will dissapear when the current block ends
|
||||
- <tt>-l</tt> or <tt>--local</tt> forces the specified environment variable to be made local to the current block, even if the variable already exists and is non-local
|
||||
- <tt>-n</tt> or <tt>--names</tt> List only the names of all defined variables
|
||||
- <tt>-x</tt> or <tt>--export</tt> causes the specified environment variable to be exported to child processes
|
||||
- <tt>-q</tt> or <tt>--query</tt> test if the specified variable names are defined. Does not output anything, but the builtins exit status is the number of variables specified that where not defined.
|
||||
- <tt>-u</tt> or <tt>--unexport</tt> causes the specified environment not to be exported to child processes
|
||||
- <tt>-U</tt> or <tt>--universal</tt> causes the specified environment variable to be made universal. If this option is supplied, the variable will be shared between all the current users fish instances on the current computer, and will be preserved across restarts of the shell.
|
||||
- <tt>-x</tt> or <tt>--export</tt> causes the specified environment variable to be exported to child processes
|
||||
|
||||
If set is called with no arguments, the names and values of all
|
||||
environment variables are printed.
|
||||
|
|
226
env.c
226
env.c
|
@ -38,8 +38,6 @@
|
|||
#include "reader.h"
|
||||
#include "parser.h"
|
||||
#include "env_universal.h"
|
||||
#include "env_universal.h"
|
||||
|
||||
|
||||
/**
|
||||
Command used to start fishd
|
||||
|
@ -119,6 +117,12 @@ static hash_table_t env_read_only;
|
|||
*/
|
||||
static char **export_arr=0;
|
||||
|
||||
/**
|
||||
Buffer used for storing string contents for export_arr
|
||||
*/
|
||||
static buffer_t export_buffer;
|
||||
|
||||
|
||||
/**
|
||||
Flag for checking if we need to regenerate the exported variable
|
||||
array
|
||||
|
@ -200,6 +204,9 @@ void env_init()
|
|||
char **p;
|
||||
|
||||
sb_init( &dyn_var );
|
||||
|
||||
b_init( &export_buffer );
|
||||
|
||||
|
||||
/*
|
||||
These variables can not be altered directly by the user
|
||||
|
@ -275,6 +282,8 @@ void env_destroy()
|
|||
// fwprintf( stderr, L"Filled %d exported vars\n", c1 );
|
||||
|
||||
sb_destroy( &dyn_var );
|
||||
|
||||
b_destroy( &export_buffer );
|
||||
|
||||
while( &top->env != global )
|
||||
env_pop();
|
||||
|
@ -285,13 +294,8 @@ void env_destroy()
|
|||
hash_destroy( global );
|
||||
free( top );
|
||||
|
||||
if( export_arr != 0 )
|
||||
{
|
||||
for( ptr = export_arr; *ptr; ptr++ )
|
||||
free( *ptr );
|
||||
|
||||
free( export_arr );
|
||||
}
|
||||
free( export_arr );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -347,7 +351,18 @@ void env_set( const wchar_t *key,
|
|||
|
||||
if( var_mode & ENV_UNIVERSAL )
|
||||
{
|
||||
env_universal_set( key, val );
|
||||
int export = 0;
|
||||
|
||||
if( !(var_mode & ENV_EXPORT ) &&
|
||||
!(var_mode & ENV_UNEXPORT ) )
|
||||
{
|
||||
env_universal_get_export( key );
|
||||
}
|
||||
else
|
||||
export = (var_mode & ENV_EXPORT );
|
||||
|
||||
env_universal_set( key, val, export );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -389,7 +404,18 @@ void env_set( const wchar_t *key,
|
|||
{
|
||||
if( env_universal_get( key ) )
|
||||
{
|
||||
env_universal_set( key, val );
|
||||
int export = 0;
|
||||
|
||||
if( !(var_mode & ENV_EXPORT ) &&
|
||||
!(var_mode & ENV_UNEXPORT ) )
|
||||
{
|
||||
env_universal_get_export( key );
|
||||
}
|
||||
else
|
||||
export = (var_mode & ENV_EXPORT );
|
||||
|
||||
env_universal_set( key, val, export );
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
@ -602,50 +628,6 @@ void env_pop()
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Recreate the table of global variables used by execv
|
||||
*/
|
||||
static void fill_arr( const void *key, const void *val, void *aux )
|
||||
{
|
||||
var_entry_t *val_entry = (var_entry_t *)val;
|
||||
if( val_entry->export )
|
||||
{
|
||||
|
||||
c1++;
|
||||
|
||||
wchar_t *wcs_val = wcsdup( val_entry->val );
|
||||
wchar_t *pos = wcs_val;
|
||||
|
||||
int *idx_ptr = (int *)aux;
|
||||
char *key_str = wcs2str((wchar_t *)key);
|
||||
|
||||
char *val_str;
|
||||
char *woot;
|
||||
|
||||
while( *pos )
|
||||
{
|
||||
if( *pos == ARRAY_SEP )
|
||||
*pos = L':';
|
||||
pos++;
|
||||
}
|
||||
|
||||
val_str = wcs2str( wcs_val );
|
||||
free( wcs_val );
|
||||
|
||||
woot = malloc( sizeof(char)*( strlen(key_str) +
|
||||
strlen(val_str) + 2) );
|
||||
|
||||
strcpy( woot, key_str );
|
||||
strcat( woot, "=" );
|
||||
strcat( woot, val_str );
|
||||
export_arr[*idx_ptr] = woot;
|
||||
(*idx_ptr)++;
|
||||
|
||||
free( key_str );
|
||||
free( val_str );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Function used with hash_foreach to insert keys of one table into
|
||||
|
@ -660,13 +642,15 @@ static void add_key_to_hash( const void *key,
|
|||
( !e->export && get_names_show_unexported) )
|
||||
hash_put( (hash_table_t *)aux, key, 0 );
|
||||
}
|
||||
static void add_universal_key_to_hash( const void *key,
|
||||
const void *data,
|
||||
void *aux )
|
||||
|
||||
static void add_to_hash( const void *k, void *aux )
|
||||
{
|
||||
hash_put( (hash_table_t *)aux, key, 0 );
|
||||
hash_put( (hash_table_t *)aux,
|
||||
k,
|
||||
0 );
|
||||
}
|
||||
|
||||
|
||||
void env_get_names( array_list_t *l, int flags )
|
||||
{
|
||||
int show_local = flags & ENV_LOCAL;
|
||||
|
@ -718,10 +702,15 @@ void env_get_names( array_list_t *l, int flags )
|
|||
|
||||
if( show_universal )
|
||||
{
|
||||
if( get_names_show_unexported )
|
||||
hash_foreach2( &env_universal_var,
|
||||
add_universal_key_to_hash,
|
||||
&names );
|
||||
array_list_t uni_list;
|
||||
al_init( &uni_list );
|
||||
|
||||
env_universal_get_names( &uni_list,
|
||||
get_names_show_exported,
|
||||
get_names_show_unexported );
|
||||
|
||||
al_foreach2( &uni_list, &add_to_hash, &names );
|
||||
al_destroy( &uni_list );
|
||||
}
|
||||
|
||||
hash_get_keys( &names, l );
|
||||
|
@ -729,35 +718,116 @@ void env_get_names( array_list_t *l, int flags )
|
|||
}
|
||||
|
||||
|
||||
char **env_export_arr()
|
||||
static void export_func1( const void *k, const void *v, void *aux )
|
||||
{
|
||||
if( has_changed )
|
||||
var_entry_t *val_entry = (var_entry_t *)v;
|
||||
if( val_entry->export )
|
||||
{
|
||||
int pos=0;
|
||||
char **ptr;
|
||||
env_node_t *n=top;
|
||||
hash_table_t *h = (hash_table_t *)aux;
|
||||
|
||||
if( export_arr != 0 )
|
||||
{
|
||||
for( ptr = export_arr; *ptr; ptr++ )
|
||||
free( *ptr );
|
||||
}
|
||||
if( !hash_get( h, k ) )
|
||||
hash_put( h, k, val_entry->val );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export_arr = realloc( export_arr,
|
||||
sizeof(char *)*(export_count + 1) );
|
||||
static void export_func2( const void *k, const void *v, void *aux )
|
||||
{
|
||||
wchar_t *key = (wchar_t *)k;
|
||||
wchar_t *val = (wchar_t *)v;
|
||||
|
||||
char *ks = wcs2str( key );
|
||||
char *vs = wcs2str( val );
|
||||
|
||||
char *pos = vs;
|
||||
|
||||
buffer_t *out = (buffer_t *)aux;
|
||||
|
||||
if( !ks || !vs )
|
||||
{
|
||||
die_mem();
|
||||
}
|
||||
|
||||
/*
|
||||
Make arrays into colon-separated lists
|
||||
*/
|
||||
while( *pos )
|
||||
{
|
||||
if( *pos == ARRAY_SEP )
|
||||
*pos = ':';
|
||||
pos++;
|
||||
}
|
||||
int nil = 0;
|
||||
|
||||
b_append( out, ks, strlen(ks) );
|
||||
b_append( out, "=", 1 );
|
||||
b_append( out, vs, strlen(vs) );
|
||||
b_append( out, &nil, 1 );
|
||||
|
||||
free( ks );
|
||||
free( vs );
|
||||
}
|
||||
|
||||
char **env_export_arr( int recalc)
|
||||
{
|
||||
if( recalc )
|
||||
env_universal_barrier();
|
||||
|
||||
if( has_changed || env_universal_update )
|
||||
{
|
||||
array_list_t uni;
|
||||
hash_table_t vals;
|
||||
env_node_t *n=top;
|
||||
int prev_was_null=1;
|
||||
int pos=0;
|
||||
int i;
|
||||
|
||||
debug( 3, L"env_export_arr()" );
|
||||
|
||||
hash_init( &vals, &hash_wcs_func, &hash_wcs_cmp );
|
||||
|
||||
while( n )
|
||||
{
|
||||
hash_foreach2( &n->env, &fill_arr, &pos );
|
||||
hash_foreach2( &n->env, &export_func1, &vals );
|
||||
|
||||
if( n->new_scope )
|
||||
n = global_env;
|
||||
else
|
||||
n = n->next;
|
||||
|
||||
n = n->next;
|
||||
}
|
||||
|
||||
al_init( &uni );
|
||||
env_universal_get_names( &uni, 1, 0 );
|
||||
for( i=0; i<al_get_count( &uni ); i++ )
|
||||
{
|
||||
wchar_t *key = (wchar_t *)al_get( &uni, i );
|
||||
wchar_t *val = env_universal_get( key );
|
||||
if( !hash_get( &vals, key ) )
|
||||
hash_put( &vals, key, val );
|
||||
}
|
||||
al_destroy( &uni );
|
||||
|
||||
export_buffer.used=0;
|
||||
|
||||
hash_foreach2( &vals, &export_func2, &export_buffer );
|
||||
hash_destroy( &vals );
|
||||
|
||||
export_arr = realloc( export_arr,
|
||||
sizeof(char *)*(hash_get_count( &vals) + 1) );
|
||||
|
||||
for( i=0; i<export_buffer.used; i++ )
|
||||
{
|
||||
if( prev_was_null )
|
||||
{
|
||||
export_arr[pos++]= &export_buffer.buff[i];
|
||||
debug( 3, L"%s", &export_buffer.buff[i]);
|
||||
}
|
||||
prev_was_null = (export_buffer.buff[i]==0);
|
||||
}
|
||||
export_arr[pos]=0;
|
||||
has_changed=0;
|
||||
env_universal_update=0;
|
||||
|
||||
}
|
||||
return export_arr;
|
||||
}
|
||||
|
|
2
env.h
2
env.h
|
@ -89,7 +89,7 @@ void env_pop();
|
|||
/**
|
||||
Returns an array containing all exported variables in a format suitable for execv.
|
||||
*/
|
||||
char **env_export_arr();
|
||||
char **env_export_arr( int recalc );
|
||||
|
||||
/**
|
||||
Insert all variable names into l. These are not copies of the strings and should not be freed after use.
|
||||
|
|
109
env_universal.c
109
env_universal.c
|
@ -41,9 +41,11 @@ wchar_t * path;
|
|||
wchar_t *user;
|
||||
void (*start_fishd)();
|
||||
|
||||
int env_universal_update=0;
|
||||
|
||||
static int barrier_reply = 0;
|
||||
|
||||
static void barrier();
|
||||
void env_universal_barrier();
|
||||
|
||||
|
||||
/**
|
||||
|
@ -109,8 +111,12 @@ static int get_socket( int fork_ok )
|
|||
if( fork_ok )
|
||||
{
|
||||
debug( 2, L"Could not connect to socket %d, starting fishd", s );
|
||||
|
||||
if( start_fishd )
|
||||
{
|
||||
start_fishd();
|
||||
}
|
||||
|
||||
return get_socket( 0 );
|
||||
}
|
||||
|
||||
|
@ -133,15 +139,35 @@ static int get_socket( int fork_ok )
|
|||
|
||||
static void callback( int type, const wchar_t *name, const wchar_t *val )
|
||||
{
|
||||
|
||||
if( type == BARRIER_REPLY )
|
||||
{
|
||||
debug( 3, L"Got barrier reply" );
|
||||
|
||||
barrier_reply = 1;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
env_universal_update=1;
|
||||
}
|
||||
}
|
||||
|
||||
static void check_connection()
|
||||
{
|
||||
if( !init )
|
||||
return;
|
||||
|
||||
if( env_universal_server.killme )
|
||||
{
|
||||
debug( 3, L"Lost connection to universal variable server." );
|
||||
close( env_universal_server.fd );
|
||||
env_universal_server.fd = -1;
|
||||
env_universal_server.killme=0;
|
||||
sb_clear( &env_universal_server.input );
|
||||
env_universal_read_all();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void env_universal_init( wchar_t * p, wchar_t *u, void (*sf)() )
|
||||
{
|
||||
|
@ -160,7 +186,7 @@ void env_universal_init( wchar_t * p, wchar_t *u, void (*sf)() )
|
|||
init = 1;
|
||||
if( env_universal_server.fd >= 0 )
|
||||
{
|
||||
barrier();
|
||||
env_universal_barrier();
|
||||
}
|
||||
debug( 2, L"end env_universal_init()" );
|
||||
}
|
||||
|
@ -208,22 +234,13 @@ int env_universal_read_all()
|
|||
init = 1;
|
||||
|
||||
if( env_universal_server.fd >= 0 )
|
||||
barrier();
|
||||
env_universal_barrier();
|
||||
}
|
||||
|
||||
if( env_universal_server.fd != -1 )
|
||||
{
|
||||
read_message( &env_universal_server );
|
||||
if( env_universal_server.killme )
|
||||
{
|
||||
debug( 2, L"Lost connection to universal variable server." );
|
||||
close( env_universal_server.fd );
|
||||
env_universal_server.fd = -1;
|
||||
env_universal_server.killme=0;
|
||||
sb_clear( &env_universal_server.input );
|
||||
|
||||
env_universal_read_all();
|
||||
}
|
||||
check_connection();
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
|
@ -235,40 +252,59 @@ int env_universal_read_all()
|
|||
|
||||
wchar_t *env_universal_get( const wchar_t *name )
|
||||
{
|
||||
debug( 3, L"env_universal_get( %ls )", name );
|
||||
if( !init)
|
||||
return 0;
|
||||
|
||||
debug( 2, L"env_universal_get( %ls )", name );
|
||||
barrier();
|
||||
|
||||
if( !name )
|
||||
return 0;
|
||||
|
||||
return (wchar_t *)hash_get( &env_universal_var, name );
|
||||
env_universal_barrier();
|
||||
|
||||
return env_universal_common_get( name );
|
||||
}
|
||||
|
||||
static void barrier()
|
||||
int env_universal_get_export( const wchar_t *name )
|
||||
{
|
||||
return env_universal_common_get_export( name );
|
||||
}
|
||||
|
||||
void env_universal_barrier()
|
||||
{
|
||||
message_t *msg;
|
||||
fd_set fds;
|
||||
|
||||
if( !init )
|
||||
return;
|
||||
|
||||
barrier_reply = 0;
|
||||
|
||||
/*
|
||||
Create barrier request
|
||||
*/
|
||||
msg= create_message( BARRIER, 0, 0);
|
||||
msg->count=1;
|
||||
q_put( &env_universal_server.unsent, msg );
|
||||
|
||||
/*
|
||||
Wait until barrier request has been sent
|
||||
*/
|
||||
debug( 3, L"Create barrier" );
|
||||
while( 1 )
|
||||
{
|
||||
try_send_all( &env_universal_server );
|
||||
check_connection();
|
||||
|
||||
if( q_empty( &env_universal_server.unsent ) )
|
||||
break;
|
||||
FD_ZERO( &fds );
|
||||
FD_SET( env_universal_server.fd, &fds );
|
||||
select( env_universal_server.fd+1, 0, &fds, 0, 0 );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Wait for barrier reply
|
||||
*/
|
||||
debug( 3, L"Sent barrier request" );
|
||||
while( !barrier_reply )
|
||||
{
|
||||
|
@ -278,25 +314,31 @@ static void barrier()
|
|||
env_universal_read_all();
|
||||
}
|
||||
debug( 3, L"End barrier" );
|
||||
|
||||
}
|
||||
|
||||
|
||||
void env_universal_set( const wchar_t *name, const wchar_t *value )
|
||||
void env_universal_set( const wchar_t *name, const wchar_t *value, int export )
|
||||
{
|
||||
message_t *msg;
|
||||
|
||||
if( !init )
|
||||
return;
|
||||
|
||||
debug( 2, 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);
|
||||
|
||||
msg= create_message( 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 );
|
||||
barrier();
|
||||
|
||||
|
||||
env_universal_barrier();
|
||||
}
|
||||
|
||||
void env_universal_remove( const wchar_t *name )
|
||||
|
@ -312,5 +354,14 @@ void env_universal_remove( const wchar_t *name )
|
|||
msg= create_message( ERASE, name, 0);
|
||||
msg->count=1;
|
||||
q_put( &env_universal_server.unsent, msg );
|
||||
barrier();
|
||||
env_universal_barrier();
|
||||
}
|
||||
|
||||
void env_universal_get_names( array_list_t *l,
|
||||
int show_exported,
|
||||
int show_unexported )
|
||||
{
|
||||
env_universal_common_get_names( l,
|
||||
show_exported,
|
||||
show_unexported );
|
||||
}
|
||||
|
|
|
@ -12,6 +12,11 @@
|
|||
*/
|
||||
extern connection_t env_universal_server;
|
||||
|
||||
/**
|
||||
Update flag. Set to 1 whenever an update has occured.
|
||||
*/
|
||||
extern int env_universal_update;
|
||||
|
||||
/**
|
||||
Initialize the envuni library
|
||||
*/
|
||||
|
@ -25,10 +30,17 @@ void env_universal_destroy();
|
|||
Get the value of a universal variable
|
||||
*/
|
||||
wchar_t *env_universal_get( const wchar_t *name );
|
||||
|
||||
/**
|
||||
Get the export flag of the variable with the specified
|
||||
name. Returns 0 if the variable doesn't exist.
|
||||
*/
|
||||
int env_universal_get_export( const wchar_t *name );
|
||||
|
||||
/**
|
||||
Set the value of a universal variable
|
||||
*/
|
||||
void env_universal_set( const wchar_t *name, const wchar_t *val );
|
||||
void env_universal_set( const wchar_t *name, const wchar_t *val, int export );
|
||||
/**
|
||||
Erase a universal variable
|
||||
*/
|
||||
|
@ -36,4 +48,10 @@ void env_universal_remove( const wchar_t *name );
|
|||
|
||||
int env_universal_read_all();
|
||||
|
||||
void env_universal_get_names( array_list_t *l,
|
||||
int show_exported,
|
||||
int show_unexported );
|
||||
|
||||
void env_universal_barrier();
|
||||
|
||||
#endif
|
||||
|
|
|
@ -35,12 +35,24 @@
|
|||
*/
|
||||
#define SET_MBS "SET"
|
||||
|
||||
/**
|
||||
Non-wide version of the set_export command
|
||||
*/
|
||||
#define SET_EXPORT_MBS "SET_EXPORT"
|
||||
|
||||
/**
|
||||
Non-wide version of the erase command
|
||||
*/
|
||||
#define ERASE_MBS "ERASE"
|
||||
|
||||
/**
|
||||
Non-wide version of the barrier command
|
||||
*/
|
||||
#define BARRIER_MBS "BARRIER"
|
||||
|
||||
/**
|
||||
Non-wide version of the barrier_reply command
|
||||
*/
|
||||
#define BARRIER_REPLY_MBS "BARRIER_REPLY"
|
||||
|
||||
/**
|
||||
|
@ -48,6 +60,19 @@
|
|||
*/
|
||||
#define PARSE_ERR L"Unable to parse universal variable message: '%ls'"
|
||||
|
||||
/**
|
||||
A variable entry. Stores the value of a variable and whether it
|
||||
should be exported. Obviously, it needs to be allocated large
|
||||
enough to fit the value string.
|
||||
*/
|
||||
typedef struct var_entry
|
||||
{
|
||||
int export; /**< Whether the variable should be exported */
|
||||
wchar_t val[0]; /**< The value of the variable */
|
||||
}
|
||||
var_entry_t;
|
||||
|
||||
|
||||
static void parse_message( wchar_t *msg,
|
||||
connection_t *src );
|
||||
|
||||
|
@ -61,6 +86,17 @@ void (*callback)( int type,
|
|||
const wchar_t *val );
|
||||
|
||||
|
||||
/**
|
||||
Variable used by env_get_names to communicate auxiliary information
|
||||
to add_key_to_hash
|
||||
*/
|
||||
static int get_names_show_exported;
|
||||
/**
|
||||
Variable used by env_get_names to communicate auxiliary information
|
||||
to add_key_to_hash
|
||||
*/
|
||||
static int get_names_show_unexported;
|
||||
|
||||
|
||||
void env_universal_common_init( void (*cb)(int type, const wchar_t *key, const wchar_t *val ) )
|
||||
{
|
||||
|
@ -155,6 +191,7 @@ static int match( const wchar_t *msg, const wchar_t *cmd )
|
|||
size_t len = wcslen( cmd );
|
||||
if( wcsncasecmp( msg, cmd, len ) != 0 )
|
||||
return 0;
|
||||
|
||||
if( msg[len] && msg[len]!= L' ' && msg[len] != L'\t' )
|
||||
return 0;
|
||||
|
||||
|
@ -169,12 +206,13 @@ static void parse_message( wchar_t *msg,
|
|||
|
||||
if( msg[0] == L'#' )
|
||||
return;
|
||||
|
||||
if( match( msg, SET_STR ) )
|
||||
|
||||
if( match( msg, SET_STR ) || match( msg, SET_EXPORT_STR ))
|
||||
{
|
||||
wchar_t *name, *val, *tmp;
|
||||
|
||||
name = msg+wcslen(SET_STR);
|
||||
int export = match( msg, SET_EXPORT_STR );
|
||||
|
||||
name = msg+(export?wcslen(SET_EXPORT_STR):wcslen(SET_STR));
|
||||
while( wcschr( L"\t ", *name ) )
|
||||
name++;
|
||||
|
||||
|
@ -189,14 +227,22 @@ static void parse_message( wchar_t *msg,
|
|||
|
||||
val = unescape( wcsdup(val), 0 );
|
||||
|
||||
var_entry_t *entry =
|
||||
malloc( sizeof(var_entry_t) + sizeof(wchar_t)*(wcslen(val)+1) );
|
||||
if( !entry )
|
||||
die_mem();
|
||||
entry->export=export;
|
||||
|
||||
wcscpy( entry->val, val );
|
||||
remove_entry( key );
|
||||
|
||||
hash_put( &env_universal_var, key, val );
|
||||
hash_put( &env_universal_var, key, entry );
|
||||
|
||||
if( callback )
|
||||
{
|
||||
callback( SET, key, val );
|
||||
callback( export?SET_EXPORT:SET, key, val );
|
||||
}
|
||||
free(val );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -205,7 +251,7 @@ static void parse_message( wchar_t *msg,
|
|||
}
|
||||
else if( match( msg, ERASE_STR ) )
|
||||
{
|
||||
wchar_t *name, *val, *tmp;
|
||||
wchar_t *name, *tmp;
|
||||
|
||||
name = msg+wcslen(ERASE_STR);
|
||||
while( wcschr( L"\t ", *name ) )
|
||||
|
@ -253,8 +299,11 @@ int try_send( message_t *msg,
|
|||
int fd )
|
||||
{
|
||||
|
||||
debug( 3,
|
||||
L"before write of %d chars to fd %d", strlen(msg->body), fd );
|
||||
|
||||
int res = write( fd, msg->body, strlen(msg->body) );
|
||||
|
||||
|
||||
if( res == -1 )
|
||||
{
|
||||
switch( errno )
|
||||
|
@ -282,12 +331,11 @@ int try_send( message_t *msg,
|
|||
|
||||
void try_send_all( connection_t *c )
|
||||
{
|
||||
debug( 2,
|
||||
debug( 3,
|
||||
L"Send all updates to connection on fd %d",
|
||||
c->fd );
|
||||
while( !q_empty( &c->unsent) )
|
||||
{
|
||||
|
||||
switch( try_send( (message_t *)q_peek( &c->unsent), c->fd ) )
|
||||
{
|
||||
case 1:
|
||||
|
@ -295,9 +343,13 @@ void try_send_all( connection_t *c )
|
|||
break;
|
||||
|
||||
case 0:
|
||||
debug( 1,
|
||||
L"Socket full, send rest later" );
|
||||
return;
|
||||
|
||||
case -1:
|
||||
debug( 1,
|
||||
L"Socket dead!!!" );
|
||||
c->killme = 1;
|
||||
return;
|
||||
}
|
||||
|
@ -329,6 +381,7 @@ message_t *create_message( int type,
|
|||
switch( type )
|
||||
{
|
||||
case SET:
|
||||
case SET_EXPORT:
|
||||
{
|
||||
if( !val_in )
|
||||
{
|
||||
|
@ -341,20 +394,20 @@ message_t *create_message( int type,
|
|||
|
||||
char *val = wcs2str(esc );
|
||||
free(esc);
|
||||
|
||||
|
||||
sz = strlen(SET_MBS) + strlen(key) + strlen(val) + 4;
|
||||
|
||||
sz = strlen(type==SET?SET_MBS:SET_EXPORT_MBS) + strlen(key) + strlen(val) + 4;
|
||||
msg = malloc( sizeof( message_t ) + sz );
|
||||
|
||||
|
||||
if( !msg )
|
||||
die_mem();
|
||||
|
||||
strcpy( msg->body, SET_MBS " " );
|
||||
|
||||
strcpy( msg->body, (type==SET?SET_MBS:SET_EXPORT_MBS) );
|
||||
strcat( msg->body, " " );
|
||||
strcat( msg->body, key );
|
||||
strcat( msg->body, ":" );
|
||||
strcat( msg->body, val );
|
||||
strcat( msg->body, "\n" );
|
||||
|
||||
|
||||
free( val );
|
||||
|
||||
break;
|
||||
|
@ -406,3 +459,68 @@ message_t *create_message( int type,
|
|||
msg->count=0;
|
||||
return msg;
|
||||
}
|
||||
|
||||
/**
|
||||
Function used with hash_foreach to insert keys of one table into
|
||||
another
|
||||
*/
|
||||
static void add_key_to_hash( const void *key,
|
||||
const void *data,
|
||||
void *aux )
|
||||
{
|
||||
var_entry_t *e = (var_entry_t *)data;
|
||||
if( ( e->export && get_names_show_exported) ||
|
||||
( !e->export && get_names_show_unexported) )
|
||||
al_push( (array_list_t *)aux, key );
|
||||
}
|
||||
|
||||
void env_universal_common_get_names( array_list_t *l,
|
||||
int show_exported,
|
||||
int show_unexported )
|
||||
{
|
||||
get_names_show_exported = show_exported;
|
||||
get_names_show_unexported = show_unexported;
|
||||
|
||||
hash_foreach2( &env_universal_var,
|
||||
add_key_to_hash,
|
||||
l );
|
||||
}
|
||||
|
||||
wchar_t *env_universal_common_get( const wchar_t *name )
|
||||
{
|
||||
var_entry_t *e = (var_entry_t *)hash_get( &env_universal_var, name );
|
||||
if( e )
|
||||
return e->val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int env_universal_common_get_export( const wchar_t *name )
|
||||
{
|
||||
var_entry_t *e = (var_entry_t *)hash_get( &env_universal_var, name );
|
||||
if( e )
|
||||
return e->export;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void enqueue( const void *k,
|
||||
const void *v,
|
||||
void *q)
|
||||
{
|
||||
const wchar_t *key = (const wchar_t *)k;
|
||||
const var_entry_t *val = (const var_entry_t *)v;
|
||||
queue_t *queue = (queue_t *)q;
|
||||
|
||||
message_t *msg = create_message( val->export?SET_EXPORT:SET, key, val->val );
|
||||
msg->count=1;
|
||||
|
||||
q_put( queue, msg );
|
||||
}
|
||||
|
||||
void enqueue_all( connection_t *c )
|
||||
{
|
||||
hash_foreach2( &env_universal_var,
|
||||
&enqueue,
|
||||
(void *)&c->unsent );
|
||||
try_send_all( c );
|
||||
}
|
||||
|
||||
|
|
|
@ -7,12 +7,24 @@
|
|||
*/
|
||||
#define SET_STR L"SET"
|
||||
|
||||
/**
|
||||
The set_export command
|
||||
*/
|
||||
#define SET_EXPORT_STR L"SET_EXPORT"
|
||||
|
||||
/**
|
||||
The erase command
|
||||
*/
|
||||
#define ERASE_STR L"ERASE"
|
||||
|
||||
/**
|
||||
The barrier command
|
||||
*/
|
||||
#define BARRIER_STR L"BARRIER"
|
||||
|
||||
/**
|
||||
The barrier_reply command
|
||||
*/
|
||||
#define BARRIER_REPLY_STR L"BARRIER_REPLY"
|
||||
|
||||
|
||||
|
@ -27,17 +39,13 @@
|
|||
enum
|
||||
{
|
||||
SET,
|
||||
SET_EXPORT,
|
||||
ERASE,
|
||||
BARRIER,
|
||||
BARRIER_REPLY,
|
||||
}
|
||||
;
|
||||
|
||||
/**
|
||||
The table of universal variables
|
||||
*/
|
||||
extern hash_table_t env_universal_var;
|
||||
|
||||
/**
|
||||
This struct represents a connection between a universal variable server/client
|
||||
*/
|
||||
|
@ -107,4 +115,25 @@ void env_universal_common_init(void (*cb)(int type, const wchar_t *key, const wc
|
|||
*/
|
||||
void env_universal_common_destroy();
|
||||
|
||||
/**
|
||||
Add all variable names to the specified list
|
||||
*/
|
||||
void env_universal_common_get_names( array_list_t *l,
|
||||
int show_exported,
|
||||
int show_unexported );
|
||||
|
||||
/**
|
||||
Get the value of the variable with the specified name
|
||||
*/
|
||||
wchar_t *env_universal_common_get( const wchar_t *name );
|
||||
|
||||
/**
|
||||
Get the export flag of the variable with the specified
|
||||
name. Returns 0 if the variable doesn't exist.
|
||||
*/
|
||||
int env_universal_common_get_export( const wchar_t *name );
|
||||
|
||||
void enqueue_all( connection_t *c );
|
||||
|
||||
|
||||
#endif
|
||||
|
|
7
exec.c
7
exec.c
|
@ -289,7 +289,7 @@ static void launch_process( process_t *p )
|
|||
|
||||
/* Set the standard input/output channels of the new process. */
|
||||
|
||||
execve (wcs2str(p->actual_cmd), wcsv2strv( (const wchar_t **) p->argv), env_export_arr() );
|
||||
execve (wcs2str(p->actual_cmd), wcsv2strv( (const wchar_t **) p->argv), env_export_arr( 0 ) );
|
||||
debug( 0,
|
||||
L"Failed to execute process %ls",
|
||||
p->actual_cmd );
|
||||
|
@ -659,7 +659,6 @@ void exec( job_t *j )
|
|||
int skip_fork;
|
||||
|
||||
/* This call is used so the global environment variable array is regenerated, if needed, before the fork. That way, we avoid a lot of duplicate work where EVERY child would need to generate it */
|
||||
env_export_arr();
|
||||
|
||||
io_data_t pipe_read, pipe_write;
|
||||
io_data_t *tmp;
|
||||
|
@ -720,6 +719,10 @@ void exec( job_t *j )
|
|||
{
|
||||
mypipe[1]=-1;
|
||||
skip_fork=0;
|
||||
|
||||
if( p->type == EXTERNAL )
|
||||
env_export_arr( 1 );
|
||||
|
||||
|
||||
/*
|
||||
Set up fd:s that will be used in the pipe
|
||||
|
|
33
fishd.c
33
fishd.c
|
@ -107,48 +107,29 @@ int get_socket()
|
|||
return s;
|
||||
}
|
||||
|
||||
void enqueue( const void *k,
|
||||
const void *v,
|
||||
void *q)
|
||||
{
|
||||
const wchar_t *key = (const wchar_t *)k;
|
||||
const wchar_t *val = (const wchar_t *)v;
|
||||
queue_t *queue = (queue_t *)q;
|
||||
|
||||
message_t *msg = create_message( SET, key, val );
|
||||
msg->count=1;
|
||||
|
||||
q_put( queue, msg );
|
||||
}
|
||||
|
||||
void enqueue_all( connection_t *c )
|
||||
{
|
||||
hash_foreach2( &env_universal_var,
|
||||
&enqueue,
|
||||
(void *)&c->unsent );
|
||||
try_send_all( c );
|
||||
}
|
||||
|
||||
void broadcast( int type, const wchar_t *key, const wchar_t *val )
|
||||
{
|
||||
connection_t *c;
|
||||
message_t *msg;
|
||||
|
||||
debug( 1, L"Got message %d %ls %ls", type, key, val );
|
||||
|
||||
if( !conn )
|
||||
return;
|
||||
|
||||
msg = create_message( type, key, val );
|
||||
|
||||
|
||||
msg = create_message( type, key, val );
|
||||
|
||||
/*
|
||||
Don't merge loops, or try_send_all can free the message prematurely
|
||||
*/
|
||||
|
||||
|
||||
for( c = conn; c; c=c->next )
|
||||
{
|
||||
msg->count++;
|
||||
q_put( &c->unsent, msg );
|
||||
}
|
||||
|
||||
|
||||
for( c = conn; c; c=c->next )
|
||||
{
|
||||
try_send_all( c );
|
||||
|
|
|
@ -7,6 +7,7 @@ complete -c set -s u -l unexport -d "Do not export variable to subprocess"
|
|||
complete -c set -s g -l global -d "Make variable scope global"
|
||||
complete -c set -s l -l local -d "Make variable scope local"
|
||||
complete -c set -s U -l universal -d "Make variable scope universal, i.e. shared between all fish terminals"
|
||||
complete -c set -s q -l query -d "Test if variable is defined"
|
||||
complete -c set -s h -l help -d "Display help and exit"
|
||||
|
||||
function __fish_set_is_first -d 'Test if no non-switch argument has been specified yet'
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
#
|
||||
# Completions for the wget command
|
||||
#
|
||||
|
||||
complete -c wget -s V -l version -d "Display version and exit"
|
||||
complete -c wget -s h -l help -d "Display help and exit"
|
||||
|
@ -20,11 +23,11 @@ complete -c wget -l no-clobber -d "Never overwrite files with same name"
|
|||
complete -c wget -o nc -d "Never overwrite files with same name"
|
||||
complete -c wget -s c -l continue -d "Continue getting a partially-downloaded file"
|
||||
complete -c wget -l progress -d "Select progress meter type" -a "
|
||||
dot\t'Print one dot for every kB of data, 50 dots per line'
|
||||
dot:default\t'Print one dot for every kB of data, 50 dots per line'
|
||||
dot:binary\t'Print one dot for every 8 kB of data, 48 dots per line'
|
||||
dot:mega\t'Print one dot for every 64 kB of data, 48 dots per line'
|
||||
bar\t'Print progress bar'
|
||||
dot\t'Print one dot for every kB of data, 50 dots per line'
|
||||
dot:default\t'Print one dot for every kB of data, 50 dots per line'
|
||||
dot:binary\t'Print one dot for every 8 kB of data, 48 dots per line'
|
||||
dot:mega\t'Print one dot for every 64 kB of data, 48 dots per line'
|
||||
bar\t'Print progress bar'
|
||||
"
|
||||
complete -c wget -s N -l timestamping -d "Turn on time-stamping"
|
||||
complete -c wget -s S -l server-response -d "Print the headers/responses sent by servers"
|
||||
|
@ -41,8 +44,8 @@ complete -c wget -s Y -l proxy -d "Toggle proxy support" -xa "on off"
|
|||
complete -c wget -s Q -l quota -d "Specify download quota for automatic retrievals" -x
|
||||
complete -c wget -l dns-cache -d "Turn off caching of DNS lookups" -xa "off"
|
||||
complete -c wget -l restrict-file-names -d "Change which characters found in remote URLs may show up in local file names" -a "
|
||||
unix\t'Escape slash and non-printing characters'
|
||||
windows\t'Escape most non-alphabetical characters'
|
||||
unix\t'Escape slash and non-printing characters'
|
||||
windows\t'Escape most non-alphabetical characters'
|
||||
"
|
||||
|
||||
# HTTP options
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
#
|
||||
# Completions for the yum command
|
||||
#
|
||||
|
||||
#Load rpm completions, since that is where the package completion function is defined
|
||||
complete -y rpm
|
||||
|
|
|
@ -53,12 +53,19 @@ end
|
|||
# Set various color values
|
||||
#
|
||||
|
||||
function set_default -d "Set a universal variable, unless it has already been set"
|
||||
if not test $$argv[1]
|
||||
function set_default -d "Set an universal variable, unless it has already been set"
|
||||
if not set -q $argv[1]
|
||||
set -U -- $argv
|
||||
end
|
||||
end
|
||||
|
||||
function set_exported_default -d "Set an exported universal variable, unless it has already been set"
|
||||
if not set -q $argv[1]
|
||||
set -Ux -- $argv
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# Regular syntax highlighting colors
|
||||
set_default fish_color_normal normal
|
||||
set_default fish_color_command green
|
||||
|
@ -83,21 +90,20 @@ set_default fish_pager_color_progress cyan
|
|||
# Directory history colors
|
||||
set_default fish_color_history_current cyan
|
||||
|
||||
functions -e set_default
|
||||
|
||||
#
|
||||
# Setup the CDPATH variable
|
||||
#
|
||||
|
||||
set -gx CDPATH . ~
|
||||
set_exported_default CDPATH . ~
|
||||
|
||||
#
|
||||
# Match colors for grep, if supported
|
||||
#
|
||||
|
||||
if grep --color=auto --help 1>/dev/null 2>/dev/null
|
||||
set -gx GREP_COLOR '97;45'
|
||||
set -gx -- GREP_OPTIONS '--color=auto'
|
||||
set_exported_default GREP_COLOR '97;45'
|
||||
set_exported_default GREP_OPTIONS '--color=auto'
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -105,6 +111,9 @@ end
|
|||
#
|
||||
|
||||
if command ls --color=auto --help 1>/dev/null 2>/dev/null
|
||||
set -gx LS_COLORS $LS_COLORS '*.jar=01;31' '*.doc=35' '*.pdf=35' '*.ps=35' '*.xls=35' '*.swf=35' '*~=37'
|
||||
set_exported_default LS_COLORS $LS_COLORS '*.jar=01;31' '*.doc=35' '*.pdf=35' '*.ps=35' '*.xls=35' '*.swf=35' '*~=37'
|
||||
end
|
||||
|
||||
|
||||
functions -e set_default
|
||||
functions -e set_exported_default
|
||||
|
|
21
key_reader.c
21
key_reader.c
|
@ -12,17 +12,7 @@
|
|||
#include <unistd.h>
|
||||
#include <termcap.h>
|
||||
|
||||
static int readch()
|
||||
{
|
||||
char arr[1];
|
||||
if( read( 0, arr, 1 ) < 0 )
|
||||
{
|
||||
perror( "read" );
|
||||
return readch();
|
||||
}
|
||||
else
|
||||
return arr[0];
|
||||
}
|
||||
#include "input_common.h"
|
||||
|
||||
int writestr( char *str )
|
||||
{
|
||||
|
@ -66,6 +56,9 @@ int main( int argc, char **argv)
|
|||
struct termios modes, /* so we can change the modes */
|
||||
savemodes; /* so we can reset the modes when we're done */
|
||||
|
||||
input_common_init(0);
|
||||
|
||||
|
||||
tcgetattr(0,&modes); /* get the current terminal modes */
|
||||
savemodes = modes; /* save a copy so we can reset them */
|
||||
|
||||
|
@ -76,9 +69,9 @@ int main( int argc, char **argv)
|
|||
tcsetattr(0,TCSANOW,&modes); /* set the new modes */
|
||||
while(1)
|
||||
{
|
||||
if( (c=readch()) == EOF )
|
||||
if( (c=input_common_readch(0)) == EOF )
|
||||
break;
|
||||
if((c > 31) && (c != 127) )
|
||||
if( (c > 31) && (c != 127) )
|
||||
sprintf( scratch, "dec: %d hex: %x char: %c\n", c, c, c );
|
||||
else
|
||||
sprintf( scratch, "dec: %d hex: %x\n", c, c );
|
||||
|
@ -86,6 +79,8 @@ int main( int argc, char **argv)
|
|||
}
|
||||
/* reset the terminal to the saved mode */
|
||||
tcsetattr(0,TCSANOW,&savemodes);
|
||||
|
||||
input_common_destroy();
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
5
parser.c
5
parser.c
|
@ -1605,10 +1605,7 @@ static void eval_job( tokenizer *tok )
|
|||
long long t1=0, t2=0, t3=0;
|
||||
profile_element_t *p=0;
|
||||
int skip = 0;
|
||||
|
||||
if( !is_block && !is_subshell )
|
||||
env_universal_read_all();
|
||||
|
||||
|
||||
if( profile )
|
||||
{
|
||||
p=malloc( sizeof(profile_element_t));
|
||||
|
|
31
proc.c
31
proc.c
|
@ -45,6 +45,7 @@ Some of the code in this file is based on code from the Glibc manual.
|
|||
#include "reader.h"
|
||||
#include "sanity.h"
|
||||
#include "env.h"
|
||||
#include "parser.h"
|
||||
|
||||
/**
|
||||
Size of message buffer
|
||||
|
@ -540,7 +541,7 @@ static void handle_child_status( pid_t pid, int status )
|
|||
int found_proc = 0;
|
||||
job_t *j;
|
||||
process_t *p;
|
||||
// char mess[MESS_SIZE];
|
||||
char mess[MESS_SIZE];
|
||||
found_proc = 0;
|
||||
/*
|
||||
snprintf( mess,
|
||||
|
@ -587,13 +588,12 @@ static void handle_child_status( pid_t pid, int status )
|
|||
}
|
||||
|
||||
|
||||
if( !is_interactive )
|
||||
if( WIFSIGNALED( status ) &&
|
||||
( WTERMSIG(status)==SIGINT ||
|
||||
WTERMSIG(status)==SIGQUIT ) )
|
||||
{
|
||||
|
||||
if( WIFSIGNALED( status ) &&
|
||||
( WTERMSIG(status)==SIGINT ||
|
||||
WTERMSIG(status)==SIGQUIT ) )
|
||||
{
|
||||
if( !is_interactive_session )
|
||||
{
|
||||
struct sigaction act;
|
||||
sigemptyset( & act.sa_mask );
|
||||
act.sa_flags=0;
|
||||
|
@ -602,6 +602,23 @@ static void handle_child_status( pid_t pid, int status )
|
|||
sigaction( SIGQUIT, &act, 0 );
|
||||
kill( getpid(), WTERMSIG(status) );
|
||||
}
|
||||
else
|
||||
{
|
||||
block_t *c = current_block;
|
||||
|
||||
snprintf( mess,
|
||||
MESS_SIZE,
|
||||
"Process %ls from job %ls exited through signal, breaking loops\n",
|
||||
p->actual_cmd,
|
||||
j->command );
|
||||
write( 2, mess, strlen(mess ));
|
||||
|
||||
while( c )
|
||||
{
|
||||
c->skip=1;
|
||||
c=c->outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( !found_proc )
|
||||
|
|
Loading…
Reference in a new issue