mirror of
https://github.com/fish-shell/fish-shell.git
synced 2025-03-15 23:22:53 +08:00
Add support for specifying event handler for calling job in command supstitution. Add psub shellscript function for process substitution
darcs-hash:20051015005126-ac50b-d2aedca3a50a78362502f3fa9dd8bf25cb7dc6e1.gz
This commit is contained in:
parent
638df31ca4
commit
9298f610f6
132
builtin.c
132
builtin.c
@ -492,7 +492,8 @@ static int builtin_functions( wchar_t **argv )
|
||||
int argc=builtin_count_args( argv );
|
||||
int list=0;
|
||||
int show_hidden=0;
|
||||
|
||||
int res = 0;
|
||||
|
||||
woptind=0;
|
||||
|
||||
const static struct woption
|
||||
@ -679,19 +680,28 @@ static int builtin_functions( wchar_t **argv )
|
||||
|
||||
default:
|
||||
{
|
||||
|
||||
for( i=woptind; i<argc; i++ )
|
||||
sb_append2( sb_out,
|
||||
L"function ",
|
||||
argv[i],
|
||||
L"\n\t",
|
||||
function_get_definition(argv[i]),
|
||||
L"\nend\n\n",
|
||||
(void *)0);
|
||||
|
||||
{
|
||||
if( !function_exists( argv[i] ) )
|
||||
res++;
|
||||
else
|
||||
{
|
||||
sb_append2( sb_out,
|
||||
L"function ",
|
||||
argv[i],
|
||||
L"\n\t",
|
||||
function_get_definition(argv[i]),
|
||||
L"\nend\n\n",
|
||||
(void *)0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return res;
|
||||
|
||||
|
||||
}
|
||||
@ -714,6 +724,17 @@ static int wcsbindingname( wchar_t *str )
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void print_block_stack( block_t *b )
|
||||
{
|
||||
if( !b )
|
||||
return;
|
||||
|
||||
wprintf( L"%ls (%d)\n", parser_get_block_desc( b->type ), b->job?b->job->job_id:-1 );
|
||||
print_block_stack( b->outer );
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
The function builtin, used for providing subroutines.
|
||||
It calls various functions from function.c to perform any heavy lifting.
|
||||
@ -855,25 +876,82 @@ static int builtin_function( wchar_t **argv )
|
||||
wchar_t *end;
|
||||
event_t *e;
|
||||
|
||||
errno = 0;
|
||||
pid = wcstol( woptarg, &end, 10 );
|
||||
if( errno || !end || *end )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
L"%ls: Invalid process id %ls\n",
|
||||
argv[0],
|
||||
woptarg );
|
||||
res=1;
|
||||
break;
|
||||
}
|
||||
|
||||
e = malloc( sizeof(event_t));
|
||||
if( !e )
|
||||
die_mem();
|
||||
e->type = EVENT_EXIT;
|
||||
e->param1.pid = (opt=='j'?-1:1)*abs(pid);
|
||||
e->function_name=0;
|
||||
al_push( events, e );
|
||||
|
||||
if( ( opt == 'j' ) &&
|
||||
( wcscasecmp( woptarg, L"caller" ) == 0 ) )
|
||||
{
|
||||
int job_id = -1;
|
||||
|
||||
if( is_subshell )
|
||||
{
|
||||
block_t *b = current_block;
|
||||
|
||||
// print_block_stack( b );
|
||||
|
||||
while( b && (b->type != SUBST) )
|
||||
b = b->outer;
|
||||
|
||||
if( b )
|
||||
{
|
||||
b=b->outer;
|
||||
}
|
||||
if( b->job )
|
||||
{
|
||||
// debug( 1, L"Found block, type is %ls", parser_get_block_desc( b->type ) );
|
||||
|
||||
job_id = b->job->job_id;
|
||||
}
|
||||
else
|
||||
{
|
||||
// debug( 1, L"Calling block is null" );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if( job_id == -1 )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
L"%ls: Cannot find calling job for event handler\n",
|
||||
argv[0] );
|
||||
res=1;
|
||||
}
|
||||
else
|
||||
{
|
||||
e->type = EVENT_JOB_ID;
|
||||
e->param1.job_id = job_id;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
errno = 0;
|
||||
pid = wcstol( woptarg, &end, 10 );
|
||||
if( errno || !end || *end )
|
||||
{
|
||||
sb_printf( sb_err,
|
||||
L"%ls: Invalid process id %ls\n",
|
||||
argv[0],
|
||||
woptarg );
|
||||
res=1;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
e->type = EVENT_EXIT;
|
||||
e->param1.pid = (opt=='j'?-1:1)*abs(pid);
|
||||
}
|
||||
if( res )
|
||||
{
|
||||
free( e );
|
||||
}
|
||||
else
|
||||
{
|
||||
e->function_name=0;
|
||||
al_push( events, e );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -927,7 +1005,7 @@ static int builtin_function( wchar_t **argv )
|
||||
wchar_t **names_arr;
|
||||
int chars=0;
|
||||
|
||||
builtin_print_help( argv[0], sb_err );
|
||||
// builtin_print_help( argv[0], sb_err );
|
||||
|
||||
sb_append( sb_err, L"Current functions are: " );
|
||||
chars += wcslen( L"Current functions are: " );
|
||||
|
@ -230,8 +230,6 @@ static void parse_message( wchar_t *msg,
|
||||
tmp = wcschr( name, L':' );
|
||||
if( tmp )
|
||||
{
|
||||
wchar_t *val_unescaped;
|
||||
|
||||
wchar_t *key =malloc( sizeof( wchar_t)*(tmp-name+1));
|
||||
memcpy( key, name, sizeof( wchar_t)*(tmp-name));
|
||||
key[tmp-name]=0;
|
||||
|
8
event.c
8
event.c
@ -95,6 +95,9 @@ static int event_match( event_t *class, event_t *instance )
|
||||
if( class->param1.pid == EVENT_ANY_PID )
|
||||
return 1;
|
||||
return class->param1.pid == instance->param1.pid;
|
||||
|
||||
case EVENT_JOB_ID:
|
||||
return class->param1.job_id == instance->param1.job_id;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -180,7 +183,6 @@ void event_remove( event_t *criterion )
|
||||
signal_handle( e.param1.signal, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -292,7 +294,7 @@ static void event_fire_internal( event_t *event, array_list_t *arguments )
|
||||
al_push( fire, criterion );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
No matches. Time to return.
|
||||
*/
|
||||
@ -362,7 +364,7 @@ static void event_fire_internal( event_t *event, array_list_t *arguments )
|
||||
}
|
||||
|
||||
/**
|
||||
Perform all pending signal events
|
||||
Handle all pending signal events
|
||||
*/
|
||||
static void event_fire_signal_events()
|
||||
{
|
||||
|
6
event.h
6
event.h
@ -23,6 +23,7 @@ enum
|
||||
EVENT_SIGNAL, /**< An event triggered by a signal */
|
||||
EVENT_VARIABLE, /**< An event triggered by a variable update */
|
||||
EVENT_EXIT, /**< An event triggered by a job or process exit */
|
||||
EVENT_JOB_ID, /**< An event triggered by a job exit */
|
||||
}
|
||||
;
|
||||
|
||||
@ -53,6 +54,11 @@ typedef struct
|
||||
Process id for process-type events. Use EVENT_ANY_PID to match any pid.
|
||||
*/
|
||||
pid_t pid;
|
||||
/**
|
||||
Job id for EVENT_JOB_ID type events
|
||||
*/
|
||||
int job_id;
|
||||
|
||||
} param1;
|
||||
|
||||
const wchar_t *function_name;
|
||||
|
@ -711,6 +711,36 @@ function type -d "Print the type of a command"
|
||||
return $status
|
||||
end
|
||||
|
||||
function psub -d "Read from stdin into a file and output the filename. Remove the file when the command that calles psub exits."
|
||||
|
||||
if not status --is-command-substitution
|
||||
echo psub: Not inside of command substitution
|
||||
end
|
||||
|
||||
# Find unique file name
|
||||
while true
|
||||
set filename /tmp/.psub.(echo %self).(random);
|
||||
if not test -e $filename
|
||||
break;
|
||||
end
|
||||
end
|
||||
|
||||
cat >$filename
|
||||
|
||||
# Find unique function name
|
||||
while true
|
||||
set funcname __fish_psub_(random);
|
||||
if not functions $funcname >/dev/null ^/dev/null
|
||||
break;
|
||||
end
|
||||
end
|
||||
|
||||
eval function $funcname --on-job-exit caller\; rm $filename\; functions -e $funcname\; end
|
||||
|
||||
echo $filename
|
||||
|
||||
end
|
||||
|
||||
|
||||
if status --is-interactive
|
||||
|
||||
|
1
main.c
1
main.c
@ -55,6 +55,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#include "intern.h"
|
||||
#include "exec.h"
|
||||
#include "event.h"
|
||||
#include "output.h"
|
||||
|
||||
/**
|
||||
Parse init files
|
||||
|
8
output.c
8
output.c
@ -258,9 +258,9 @@ int writech( wint_t ch )
|
||||
*/
|
||||
void writestr( const wchar_t *str )
|
||||
{
|
||||
while( *str )
|
||||
writech( *str++ );
|
||||
/*
|
||||
// while( *str )
|
||||
// writech( *str++ );
|
||||
|
||||
size_t len = MAX_UTF8_BYTES*wcslen(str)+1;
|
||||
|
||||
if( writestr_buff_sz < len )
|
||||
@ -276,7 +276,7 @@ void writestr( const wchar_t *str )
|
||||
writestr_buff_sz );
|
||||
|
||||
write( 1, writestr_buff, strlen( writestr_buff ) );
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
12
parser.c
12
parser.c
@ -176,7 +176,8 @@ void parser_push_block( int type )
|
||||
if( type == TOP || type == SUBST )
|
||||
new->skip = 0;
|
||||
|
||||
|
||||
new->job = 0;
|
||||
|
||||
new->loop_status=LOOP_NORMAL;
|
||||
|
||||
current_block = new;
|
||||
@ -1681,7 +1682,9 @@ static void eval_job( tokenizer *tok )
|
||||
j->fg=1;
|
||||
j->constructed=0;
|
||||
j->skip_notification = is_subshell || is_block || is_event || (!is_interactive);
|
||||
|
||||
|
||||
current_block->job = j;
|
||||
|
||||
proc_had_barrier=0;
|
||||
|
||||
if( is_interactive )
|
||||
@ -1733,7 +1736,7 @@ static void eval_job( tokenizer *tok )
|
||||
p->cmd = wcsdup( j->command );
|
||||
p->skipped=current_block->skip;
|
||||
}
|
||||
|
||||
|
||||
skip |= current_block->skip;
|
||||
|
||||
if(!skip )
|
||||
@ -1785,6 +1788,7 @@ static void eval_job( tokenizer *tok )
|
||||
*/
|
||||
job_free( j );
|
||||
}
|
||||
current_block->job = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1889,7 +1893,7 @@ int eval( const wchar_t *cmd, io_data_t *io, int block_type )
|
||||
exit(1);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if( (!error_code) && (!exit_status()) && (!proc_get_last_status()) )
|
||||
{
|
||||
char *h;
|
||||
|
5
parser.h
5
parser.h
@ -25,6 +25,11 @@ typedef struct block
|
||||
*/
|
||||
int loop_status;
|
||||
|
||||
/**
|
||||
The log that is currently evaluated in the specified block.
|
||||
*/
|
||||
job_t *job;
|
||||
|
||||
/**
|
||||
First block type specific variable
|
||||
*/
|
||||
|
11
proc.c
11
proc.c
@ -482,7 +482,7 @@ static void format_job_info( const job_t *j, const wchar_t *status )
|
||||
fwprintf (stdout, L"\n" );
|
||||
}
|
||||
|
||||
static void fire_process_event( const wchar_t *msg, pid_t pid, int status )
|
||||
static void fire_process_event( const wchar_t *msg, int type, pid_t pid, int status )
|
||||
{
|
||||
static event_t ev;
|
||||
event_t e;
|
||||
@ -490,7 +490,7 @@ static void fire_process_event( const wchar_t *msg, pid_t pid, int status )
|
||||
|
||||
e.function_name=0;
|
||||
|
||||
ev.type=EVENT_EXIT;
|
||||
ev.type=type;
|
||||
ev.param1.pid = pid;
|
||||
|
||||
al_push( &event_arg, msg );
|
||||
@ -516,7 +516,7 @@ int job_reap( int interactive )
|
||||
|
||||
locked++;
|
||||
if( locked>1 )
|
||||
return;
|
||||
return 0;
|
||||
|
||||
for( j=first_job; j; j=jnext)
|
||||
{
|
||||
@ -539,7 +539,7 @@ int job_reap( int interactive )
|
||||
|
||||
s = p->status;
|
||||
|
||||
fire_process_event( L"PROCESS_EXIT", p->pid, ( WIFSIGNALED(s)?-1:WEXITSTATUS( s )) );
|
||||
fire_process_event( L"PROCESS_EXIT", EVENT_EXIT, p->pid, ( WIFSIGNALED(s)?-1:WEXITSTATUS( s )) );
|
||||
|
||||
if( WIFSIGNALED(s) )
|
||||
{
|
||||
@ -597,7 +597,8 @@ int job_reap( int interactive )
|
||||
found=1;
|
||||
}
|
||||
}
|
||||
fire_process_event( L"JOB_EXIT", -j->pgid, 0 );
|
||||
fire_process_event( L"JOB_EXIT", EVENT_EXIT, -j->pgid, 0 );
|
||||
fire_process_event( L"JOB_EXIT", EVENT_JOB_ID, j->job_id, 0 );
|
||||
|
||||
job_free(j);
|
||||
}
|
||||
|
4
reader.c
4
reader.c
@ -71,6 +71,7 @@ commence.
|
||||
#include "input.h"
|
||||
#include "function.h"
|
||||
#include "output.h"
|
||||
#include "signal.h"
|
||||
|
||||
/**
|
||||
Maximum length of prefix string when printing completion
|
||||
@ -238,9 +239,6 @@ static reader_data_t *data=0;
|
||||
*/
|
||||
static int end_loop = 0;
|
||||
|
||||
|
||||
static int new_size=0;
|
||||
|
||||
/**
|
||||
The list containing names of files that are being parsed
|
||||
*/
|
||||
|
@ -656,5 +656,4 @@ int main( int argc, char **argv )
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
8
util.c
8
util.c
@ -872,9 +872,13 @@ void sb_append2( string_buffer_t *b, ... )
|
||||
int sb_printf( string_buffer_t *buffer, const wchar_t *format, ... )
|
||||
{
|
||||
va_list va;
|
||||
int res;
|
||||
|
||||
va_start( va, format );
|
||||
sb_vprintf( buffer, format, va );
|
||||
va_end( va );
|
||||
res = sb_vprintf( buffer, format, va );
|
||||
va_end( va );
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int sb_vprintf( string_buffer_t *buffer, const wchar_t *format, va_list va_orig )
|
||||
|
2
wutil.c
2
wutil.c
@ -12,6 +12,7 @@
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <wchar.h>
|
||||
#include <wctype.h>
|
||||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
#include <stdarg.h>
|
||||
@ -240,7 +241,6 @@ static int vgwprintf( void (*writer)(wchar_t),
|
||||
{
|
||||
if(*filter == L'%')
|
||||
{
|
||||
int i;
|
||||
int is_long=0;
|
||||
int width = -1;
|
||||
filter++;
|
||||
|
Loading…
x
Reference in New Issue
Block a user