mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-26 12:53:13 +00:00
Make escaping consistent for fish <-> fishd protocol
Fix fork guards to work in fishd https://github.com/fish-shell/fish-shell/issues/339
This commit is contained in:
parent
b67526aae8
commit
51de26960c
7 changed files with 69 additions and 27 deletions
5
env.cpp
5
env.cpp
|
@ -375,7 +375,7 @@ static void react_to_variable_change(const wcstring &key) {
|
||||||
Universal variable callback function. This function makes sure the
|
Universal variable callback function. This function makes sure the
|
||||||
proper events are triggered when an event occurs.
|
proper events are triggered when an event occurs.
|
||||||
*/
|
*/
|
||||||
static void universal_callback( int type,
|
static void universal_callback( fish_message_type_t type,
|
||||||
const wchar_t *name,
|
const wchar_t *name,
|
||||||
const wchar_t *val )
|
const wchar_t *val )
|
||||||
{
|
{
|
||||||
|
@ -395,6 +395,9 @@ static void universal_callback( int type,
|
||||||
str=L"ERASE";
|
str=L"ERASE";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( str )
|
if( str )
|
||||||
|
|
|
@ -61,7 +61,7 @@ static int get_socket_count = 0;
|
||||||
static wchar_t * path;
|
static wchar_t * path;
|
||||||
static wchar_t *user;
|
static wchar_t *user;
|
||||||
static void (*start_fishd)();
|
static void (*start_fishd)();
|
||||||
static void (*external_callback)( int type, const wchar_t *name, const wchar_t *val );
|
static void (*external_callback)( fish_message_type_t type, const wchar_t *name, const wchar_t *val );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Flag set to 1 when a barrier reply is recieved
|
Flag set to 1 when a barrier reply is recieved
|
||||||
|
@ -165,7 +165,7 @@ static int get_socket( int fork_ok )
|
||||||
/**
|
/**
|
||||||
Callback function used whenever a new fishd message is recieved
|
Callback function used whenever a new fishd message is recieved
|
||||||
*/
|
*/
|
||||||
static void callback( int type, const wchar_t *name, const wchar_t *val )
|
static void callback( fish_message_type_t type, const wchar_t *name, const wchar_t *val )
|
||||||
{
|
{
|
||||||
if( type == BARRIER_REPLY )
|
if( type == BARRIER_REPLY )
|
||||||
{
|
{
|
||||||
|
@ -250,7 +250,7 @@ static void reconnect()
|
||||||
void env_universal_init( wchar_t * p,
|
void env_universal_init( wchar_t * p,
|
||||||
wchar_t *u,
|
wchar_t *u,
|
||||||
void (*sf)(),
|
void (*sf)(),
|
||||||
void (*cb)( int type, const wchar_t *name, const wchar_t *val ))
|
void (*cb)( fish_message_type_t type, const wchar_t *name, const wchar_t *val ))
|
||||||
{
|
{
|
||||||
path=p;
|
path=p;
|
||||||
user=u;
|
user=u;
|
||||||
|
|
|
@ -20,7 +20,7 @@ extern connection_t env_universal_server;
|
||||||
void env_universal_init( wchar_t * p,
|
void env_universal_init( wchar_t * p,
|
||||||
wchar_t *u,
|
wchar_t *u,
|
||||||
void (*sf)(),
|
void (*sf)(),
|
||||||
void (*cb)( int type, const wchar_t *name, const wchar_t *val ));
|
void (*cb)( fish_message_type_t type, const wchar_t *name, const wchar_t *val ));
|
||||||
/**
|
/**
|
||||||
Free memory used by envuni
|
Free memory used by envuni
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -112,7 +112,7 @@ env_var_table_t env_universal_var;
|
||||||
/**
|
/**
|
||||||
Callback function, should be called on all events
|
Callback function, should be called on all events
|
||||||
*/
|
*/
|
||||||
void (*callback)( int type,
|
static void (*callback)( fish_message_type_t type,
|
||||||
const wchar_t *key,
|
const wchar_t *key,
|
||||||
const wchar_t *val );
|
const wchar_t *val );
|
||||||
|
|
||||||
|
@ -405,7 +405,7 @@ static char *wcs2utf( const wchar_t *in )
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void env_universal_common_init( void (*cb)(int type, const wchar_t *key, const wchar_t *val ) )
|
void env_universal_common_init( void (*cb)(fish_message_type_t type, const wchar_t *key, const wchar_t *val ) )
|
||||||
{
|
{
|
||||||
callback = cb;
|
callback = cb;
|
||||||
}
|
}
|
||||||
|
@ -592,7 +592,7 @@ void env_universal_common_set( const wchar_t *key, const wchar_t *val, int expor
|
||||||
/**
|
/**
|
||||||
Parse message msg
|
Parse message msg
|
||||||
*/
|
*/
|
||||||
static void parse_message( wchar_t *msg,
|
static void parse_message( wchar_t *msg,
|
||||||
connection_t *src )
|
connection_t *src )
|
||||||
{
|
{
|
||||||
// debug( 3, L"parse_message( %ls );", msg );
|
// debug( 3, L"parse_message( %ls );", msg );
|
||||||
|
@ -622,7 +622,8 @@ static void parse_message( wchar_t *msg,
|
||||||
val = tmp+1;
|
val = tmp+1;
|
||||||
val = unescape( val, 0 );
|
val = unescape( val, 0 );
|
||||||
|
|
||||||
env_universal_common_set( key, val, exportv );
|
if (key && val)
|
||||||
|
env_universal_common_set( key, val, exportv );
|
||||||
|
|
||||||
free( val );
|
free( val );
|
||||||
free( key );
|
free( key );
|
||||||
|
@ -752,6 +753,15 @@ void try_send_all( connection_t *c )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The universal variable format has some funny escaping requirements; here we try to be safe */
|
||||||
|
static bool is_universal_safe_to_encode_directly(wchar_t c)
|
||||||
|
{
|
||||||
|
if (c < 32 || c > 128)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return iswalnum(c) || wcschr(L"/", c);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Escape specified string
|
Escape specified string
|
||||||
*/
|
*/
|
||||||
|
@ -760,21 +770,22 @@ static wcstring full_escape( const wchar_t *in )
|
||||||
wcstring out;
|
wcstring out;
|
||||||
for( ; *in; in++ )
|
for( ; *in; in++ )
|
||||||
{
|
{
|
||||||
if( *in < 32 )
|
wchar_t c = *in;
|
||||||
|
if (is_universal_safe_to_encode_directly(c))
|
||||||
|
{
|
||||||
|
out.push_back(c);
|
||||||
|
}
|
||||||
|
else if (c < 256)
|
||||||
{
|
{
|
||||||
append_format( out, L"\\x%.2x", *in );
|
append_format(out, L"\\x%.2x", c);
|
||||||
}
|
}
|
||||||
else if( *in < 128 )
|
else if (c < 65536)
|
||||||
{
|
{
|
||||||
out.push_back(*in);
|
append_format(out, L"\\u%.4x", c);
|
||||||
}
|
|
||||||
else if( *in < 65536 )
|
|
||||||
{
|
|
||||||
append_format( out, L"\\u%.4x", *in );
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
append_format( out, L"\\U%.8x", *in );
|
append_format(out, L"\\U%.8x", c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
|
@ -803,7 +814,7 @@ void set_body(message_t *msg, ...)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns an instance of message_t allocated via new */
|
/* Returns an instance of message_t allocated via new */
|
||||||
message_t *create_message( int type,
|
message_t *create_message( fish_message_type_t type,
|
||||||
const wchar_t *key_in,
|
const wchar_t *key_in,
|
||||||
const wchar_t *val_in )
|
const wchar_t *val_in )
|
||||||
{
|
{
|
||||||
|
|
|
@ -40,15 +40,14 @@
|
||||||
/**
|
/**
|
||||||
The different types of commands that can be sent between client/server
|
The different types of commands that can be sent between client/server
|
||||||
*/
|
*/
|
||||||
enum
|
typedef enum
|
||||||
{
|
{
|
||||||
SET,
|
SET,
|
||||||
SET_EXPORT,
|
SET_EXPORT,
|
||||||
ERASE,
|
ERASE,
|
||||||
BARRIER,
|
BARRIER,
|
||||||
BARRIER_REPLY,
|
BARRIER_REPLY,
|
||||||
}
|
} fish_message_type_t;
|
||||||
;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The size of the buffer used for reading from the socket
|
The size of the buffer used for reading from the socket
|
||||||
|
@ -133,12 +132,12 @@ void try_send_all( connection_t *c );
|
||||||
/**
|
/**
|
||||||
Create a messge with the specified properties
|
Create a messge with the specified properties
|
||||||
*/
|
*/
|
||||||
message_t *create_message( int type, const wchar_t *key, const wchar_t *val );
|
message_t *create_message( fish_message_type_t type, const wchar_t *key, const wchar_t *val );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Init the library
|
Init the library
|
||||||
*/
|
*/
|
||||||
void env_universal_common_init(void (*cb)(int type, const wchar_t *key, const wchar_t *val ) );
|
void env_universal_common_init(void (*cb)(fish_message_type_t type, const wchar_t *key, const wchar_t *val ) );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Destroy library data
|
Destroy library data
|
||||||
|
|
29
fish.cpp
29
fish.cpp
|
@ -410,10 +410,34 @@ static int fish_parse_opt( int argc, char **argv, const char **cmd_ptr )
|
||||||
parses commands from stdin or files, depending on arguments
|
parses commands from stdin or files, depending on arguments
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static wcstring full_escape( const wchar_t *in )
|
||||||
|
{
|
||||||
|
wcstring out;
|
||||||
|
for( ; *in; in++ )
|
||||||
|
{
|
||||||
|
if( *in < 32 )
|
||||||
|
{
|
||||||
|
append_format( out, L"\\x%.2x", *in );
|
||||||
|
}
|
||||||
|
else if( *in < 128 )
|
||||||
|
{
|
||||||
|
out.push_back(*in);
|
||||||
|
}
|
||||||
|
else if( *in < 65536 )
|
||||||
|
{
|
||||||
|
append_format( out, L"\\u%.4x", *in );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
append_format( out, L"\\U%.8x", *in );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
extern int g_fork_count;
|
extern int g_fork_count;
|
||||||
int main( int argc, char **argv )
|
int main( int argc, char **argv )
|
||||||
{
|
{
|
||||||
struct stat tmp;
|
|
||||||
int res=1;
|
int res=1;
|
||||||
const char *cmd=0;
|
const char *cmd=0;
|
||||||
int my_optind=0;
|
int my_optind=0;
|
||||||
|
@ -425,7 +449,8 @@ int main( int argc, char **argv )
|
||||||
is_interactive_session=1;
|
is_interactive_session=1;
|
||||||
program_name=L"fish";
|
program_name=L"fish";
|
||||||
|
|
||||||
stat("----------FISH_HIT_MAIN----------", &tmp);
|
//struct stat tmp;
|
||||||
|
//stat("----------FISH_HIT_MAIN----------", &tmp);
|
||||||
|
|
||||||
my_optind = fish_parse_opt( argc, argv, &cmd );
|
my_optind = fish_parse_opt( argc, argv, &cmd );
|
||||||
|
|
||||||
|
|
|
@ -496,7 +496,7 @@ unlock:
|
||||||
/**
|
/**
|
||||||
Event handler. Broadcasts updates to all clients.
|
Event handler. Broadcasts updates to all clients.
|
||||||
*/
|
*/
|
||||||
static void broadcast( int type, const wchar_t *key, const wchar_t *val )
|
static void broadcast( fish_message_type_t type, const wchar_t *key, const wchar_t *val )
|
||||||
{
|
{
|
||||||
connection_t *c;
|
connection_t *c;
|
||||||
message_t *msg;
|
message_t *msg;
|
||||||
|
@ -540,6 +540,9 @@ static void daemonize()
|
||||||
|
|
||||||
case 0:
|
case 0:
|
||||||
{
|
{
|
||||||
|
/* Ordinarily there's very limited things we will do after fork, due to multithreading. But fishd is safe because it's single threaded. So don't die in is_forked_child. */
|
||||||
|
setup_fork_guards();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Make fishd ignore the HUP signal.
|
Make fishd ignore the HUP signal.
|
||||||
*/
|
*/
|
||||||
|
@ -557,6 +560,7 @@ static void daemonize()
|
||||||
act.sa_handler=&handle_term;
|
act.sa_handler=&handle_term;
|
||||||
sigaction( SIGTERM, &act, 0);
|
sigaction( SIGTERM, &act, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
Loading…
Reference in a new issue