mirror of
https://github.com/fish-shell/fish-shell
synced 2025-01-13 05:28:49 +00:00
Convert jobs list to std::list
This commit is contained in:
parent
1a5d866a91
commit
f243cd86c9
6 changed files with 123 additions and 97 deletions
31
builtin.cpp
31
builtin.cpp
|
@ -2906,25 +2906,7 @@ static int builtin_source( parser_t &parser, wchar_t ** argv )
|
|||
*/
|
||||
static void make_first( job_t *j )
|
||||
{
|
||||
job_t *prev=0;
|
||||
job_t *curr;
|
||||
for( curr = first_job; curr != j; curr = curr->next )
|
||||
{
|
||||
prev=curr;
|
||||
}
|
||||
if( curr == j )
|
||||
{
|
||||
if( prev == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
prev->next = curr->next;
|
||||
curr->next = first_job;
|
||||
first_job = curr;
|
||||
}
|
||||
}
|
||||
job_promote(j);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2933,7 +2915,7 @@ static void make_first( job_t *j )
|
|||
*/
|
||||
static int builtin_fg( parser_t &parser, wchar_t **argv )
|
||||
{
|
||||
job_t *j=0;
|
||||
job_t *j=NULL;
|
||||
|
||||
if( argv[1] == 0 )
|
||||
{
|
||||
|
@ -2941,7 +2923,9 @@ static int builtin_fg( parser_t &parser, wchar_t **argv )
|
|||
Select last constructed job (I.e. first job in the job que)
|
||||
that is possible to put in the foreground
|
||||
*/
|
||||
for( j=first_job; j; j=j->next )
|
||||
|
||||
job_iterator_t jobs;
|
||||
while ((j = jobs.next()))
|
||||
{
|
||||
if( job_get_flag( j, JOB_CONSTRUCTED ) && (!job_is_completed(j)) &&
|
||||
( (job_is_stopped(j) || (!job_get_flag(j, JOB_FOREGROUND)) ) && job_get_flag( j, JOB_CONTROL) ) )
|
||||
|
@ -3121,8 +3105,9 @@ static int builtin_bg( parser_t &parser, wchar_t **argv )
|
|||
if( argv[1] == 0 )
|
||||
{
|
||||
job_t *j;
|
||||
for( j=first_job; j; j=j->next )
|
||||
{
|
||||
job_iterator_t jobs;
|
||||
while ((j = jobs.next()))
|
||||
{
|
||||
if( job_is_stopped(j) && job_get_flag( j, JOB_CONTROL ) && (!job_is_completed(j)) )
|
||||
{
|
||||
break;
|
||||
|
|
|
@ -271,8 +271,11 @@ static int builtin_jobs( parser_t &parser, wchar_t **argv )
|
|||
/*
|
||||
Ignore unconstructed jobs, i.e. ourself.
|
||||
*/
|
||||
for( j=first_job; j; j=j->next )
|
||||
job_iterator_t jobs;
|
||||
job_t *j;
|
||||
while ((j = jobs.next()))
|
||||
{
|
||||
|
||||
if( (j->flags & JOB_CONSTRUCTED) && !job_is_completed(j) )
|
||||
{
|
||||
builtin_jobs_print( j, mode, !found );
|
||||
|
@ -322,8 +325,10 @@ static int builtin_jobs( parser_t &parser, wchar_t **argv )
|
|||
}
|
||||
else
|
||||
{
|
||||
for( j= first_job; j; j=j->next )
|
||||
{
|
||||
job_iterator_t jobs;
|
||||
job_t *j;
|
||||
while ((j = jobs.next()))
|
||||
{
|
||||
/*
|
||||
Ignore unconstructed jobs, i.e. ourself.
|
||||
*/
|
||||
|
|
|
@ -397,7 +397,8 @@ static int find_process( const wchar_t *proc,
|
|||
|
||||
if( flags & ACCEPT_INCOMPLETE )
|
||||
{
|
||||
for( j=first_job; j != 0; j=j->next )
|
||||
job_iterator_t jobs;
|
||||
while ((j = jobs.next()))
|
||||
{
|
||||
wchar_t jid[16];
|
||||
if( j->command == 0 )
|
||||
|
@ -454,7 +455,8 @@ static int find_process( const wchar_t *proc,
|
|||
if( found )
|
||||
return 1;
|
||||
|
||||
for( j=first_job; j != 0; j=j->next )
|
||||
job_iterator_t jobs;
|
||||
while ((j = jobs.next()))
|
||||
{
|
||||
int offset;
|
||||
|
||||
|
@ -487,7 +489,8 @@ static int find_process( const wchar_t *proc,
|
|||
return 1;
|
||||
}
|
||||
|
||||
for( j=first_job; j; j=j->next )
|
||||
jobs.reset();
|
||||
while ((j = jobs.next()))
|
||||
{
|
||||
process_t *p;
|
||||
if( j->command == 0 )
|
||||
|
|
111
proc.cpp
111
proc.cpp
|
@ -95,7 +95,12 @@ static int last_status=0;
|
|||
*/
|
||||
static sig_atomic_t got_signal=0;
|
||||
|
||||
job_t *first_job=0;
|
||||
static std::list<job_t *> s_job_list;
|
||||
|
||||
job_list_t &job_list(void) {
|
||||
return s_job_list;
|
||||
}
|
||||
|
||||
int is_interactive=-1;
|
||||
int is_interactive_session=0;
|
||||
int is_subshell=0;
|
||||
|
@ -143,25 +148,26 @@ void proc_init()
|
|||
*/
|
||||
static int job_remove( job_t *j )
|
||||
{
|
||||
job_t *prev=0, *curr=first_job;
|
||||
while( (curr != 0) && (curr != j) )
|
||||
{
|
||||
prev = curr;
|
||||
curr = curr->next;
|
||||
}
|
||||
|
||||
if( j != curr )
|
||||
{
|
||||
job_list_t &jobs = job_list();
|
||||
job_list_t::iterator iter = find(jobs.begin(), jobs.end(), j);
|
||||
if (iter != jobs.end()) {
|
||||
jobs.erase(iter);
|
||||
return 1;
|
||||
} else {
|
||||
debug( 1, _( L"Job inconsistency" ) );
|
||||
sanity_lose();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( prev == 0 )
|
||||
first_job = j->next;
|
||||
else
|
||||
prev->next = j->next;
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void job_promote(job_t *job)
|
||||
{
|
||||
job_list_t &jobs = job_list();
|
||||
job_list_t::iterator loc = find(jobs.begin(), jobs.end(), job);
|
||||
assert(loc != jobs.end());
|
||||
|
||||
/* Move the job to the beginning */
|
||||
jobs.splice(jobs.begin(), jobs, loc);
|
||||
}
|
||||
|
||||
|
||||
|
@ -181,10 +187,12 @@ void proc_destroy()
|
|||
event.arguments = NULL;
|
||||
sb_destroy( &event_pid );
|
||||
sb_destroy( &event_status );
|
||||
while( first_job )
|
||||
job_list_t &jobs = job_list();
|
||||
while( ! jobs.empty() )
|
||||
{
|
||||
debug( 2, L"freeing leaked job %ls", first_job->command );
|
||||
job_free( first_job );
|
||||
job_t *job = jobs.front();
|
||||
debug( 2, L"freeing leaked job %ls", job->command );
|
||||
job_free( job );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -206,10 +214,9 @@ job_t *job_create()
|
|||
while( job_get( free_id ) != 0 )
|
||||
free_id++;
|
||||
res = (job_t *)halloc( 0, sizeof(job_t) );
|
||||
res->next = first_job;
|
||||
res->job_id = free_id;
|
||||
first_job = res;
|
||||
|
||||
job_list().push_front(res);
|
||||
|
||||
job_set_flag( res,
|
||||
JOB_CONTROL,
|
||||
(job_control_mode==JOB_CONTROL_ALL) ||
|
||||
|
@ -223,30 +230,22 @@ job_t *job_create()
|
|||
|
||||
job_t *job_get( int id )
|
||||
{
|
||||
job_t *res = first_job;
|
||||
if( id <= 0 )
|
||||
{
|
||||
return res;
|
||||
job_iterator_t jobs;
|
||||
job_t *job;
|
||||
while ((job = jobs.next())) {
|
||||
if( id <= 0 || job->job_id == id)
|
||||
return job;
|
||||
}
|
||||
|
||||
while( res != 0 )
|
||||
{
|
||||
if( res->job_id == id )
|
||||
return res;
|
||||
res = res->next;
|
||||
}
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
job_t *job_get_from_pid( int pid )
|
||||
{
|
||||
job_t *res = first_job;
|
||||
|
||||
while( res != 0 )
|
||||
{
|
||||
if( res->pgid == pid )
|
||||
return res;
|
||||
res = res->next;
|
||||
job_iterator_t jobs;
|
||||
job_t *job;
|
||||
while ((job = jobs.next())) {
|
||||
if( job->pgid == pid )
|
||||
return job;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -399,7 +398,8 @@ static void handle_child_status( pid_t pid, int status )
|
|||
write( 2, mess, strlen(mess ));
|
||||
*/
|
||||
|
||||
for( j=first_job; j && !found_proc; j=j->next )
|
||||
job_iterator_t jobs;
|
||||
while ((j = jobs.next()))
|
||||
{
|
||||
process_t *prev=0;
|
||||
for( p=j->first_process; p; p=p->next )
|
||||
|
@ -546,7 +546,7 @@ void proc_fire_event( const wchar_t *msg, int type, pid_t pid, int status )
|
|||
|
||||
int job_reap( int interactive )
|
||||
{
|
||||
job_t *j, *jnext;
|
||||
job_t *jnext;
|
||||
int found=0;
|
||||
|
||||
static int locked = 0;
|
||||
|
@ -559,11 +559,14 @@ int job_reap( int interactive )
|
|||
*/
|
||||
if( locked>1 )
|
||||
return 0;
|
||||
|
||||
for( j=first_job; j; j=jnext)
|
||||
{
|
||||
|
||||
job_iterator_t jobs;
|
||||
jnext = jobs.next();
|
||||
while (jnext)
|
||||
{
|
||||
job_t *j = jnext;
|
||||
jnext = jobs.next();
|
||||
process_t *p;
|
||||
jnext = j->next;
|
||||
|
||||
/*
|
||||
If we are reaping only jobs who do not need status messages
|
||||
|
@ -960,9 +963,7 @@ void job_continue (job_t *j, int cont)
|
|||
/*
|
||||
Put job first in the job list
|
||||
*/
|
||||
job_remove( j );
|
||||
j->next = first_job;
|
||||
first_job = j;
|
||||
job_promote(j);
|
||||
job_set_flag( j, JOB_NOTIFIED, 0 );
|
||||
|
||||
CHECK_BLOCK();
|
||||
|
@ -1160,7 +1161,8 @@ void proc_sanity_check()
|
|||
job_t *j;
|
||||
job_t *fg_job=0;
|
||||
|
||||
for( j = first_job; j ; j=j->next )
|
||||
job_iterator_t jobs;
|
||||
while ((j = jobs.next()))
|
||||
{
|
||||
process_t *p;
|
||||
|
||||
|
@ -1174,9 +1176,6 @@ void proc_sanity_check()
|
|||
validate_pointer( j->first_process,
|
||||
_( L"Process list pointer" ),
|
||||
0 );
|
||||
validate_pointer( j->next,
|
||||
_( L"Job list pointer" ),
|
||||
1 );
|
||||
|
||||
/*
|
||||
More than one foreground job?
|
||||
|
|
50
proc.h
50
proc.h
|
@ -15,6 +15,7 @@
|
|||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <list>
|
||||
|
||||
#include "util.h"
|
||||
#include "io.h"
|
||||
|
@ -233,14 +234,15 @@ typedef struct process
|
|||
A struct represeting a job. A job is basically a pipeline of one
|
||||
or more processes and a couple of flags.
|
||||
*/
|
||||
typedef struct job
|
||||
class job_t
|
||||
{
|
||||
public:
|
||||
/**
|
||||
The original command which led to the creation of this
|
||||
job. It is used for displaying messages about job status
|
||||
on the terminal.
|
||||
*/
|
||||
const wchar_t *command;
|
||||
const wchar_t *command;
|
||||
|
||||
/**
|
||||
A linked list of all the processes in this job.
|
||||
|
@ -276,15 +278,14 @@ typedef struct job
|
|||
/**
|
||||
A pointer to the next job in the job queue
|
||||
*/
|
||||
struct job *next;
|
||||
//struct job *next;
|
||||
|
||||
/**
|
||||
Bitset containing information about the job. A combination of the JOB_* constants.
|
||||
*/
|
||||
int flags;
|
||||
|
||||
}
|
||||
job_t;
|
||||
};
|
||||
|
||||
/**
|
||||
Whether we are running a subshell command
|
||||
|
@ -316,10 +317,35 @@ extern int is_login;
|
|||
*/
|
||||
extern int is_event;
|
||||
|
||||
/**
|
||||
Linked list of all living jobs
|
||||
*/
|
||||
extern job_t *first_job;
|
||||
|
||||
/** List of all living jobs */
|
||||
typedef std::list<job_t *> job_list_t;
|
||||
job_list_t &job_list(void);
|
||||
|
||||
/** A class to aid iteration over jobs list */
|
||||
class job_iterator_t {
|
||||
job_list_t::iterator current, end;
|
||||
public:
|
||||
|
||||
void reset(void) {
|
||||
job_list_t &jobs = job_list();
|
||||
this->current = jobs.begin();
|
||||
this->end = jobs.end();
|
||||
}
|
||||
|
||||
job_t *next() {
|
||||
job_t *job = NULL;
|
||||
if (current != end) {
|
||||
job = *current;
|
||||
++current;
|
||||
}
|
||||
return job;
|
||||
}
|
||||
|
||||
job_iterator_t() {
|
||||
this->reset();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
Whether a universal variable barrier roundtrip has already been
|
||||
|
@ -377,6 +403,11 @@ int proc_get_last_status();
|
|||
*/
|
||||
void job_free( job_t* j );
|
||||
|
||||
/**
|
||||
Promotes a job to the front of the job list.
|
||||
*/
|
||||
void job_promote(job_t *job);
|
||||
|
||||
/**
|
||||
Create a new job. Job struct is allocated using halloc, so anything
|
||||
that should be freed with the job can uset it as a halloc context
|
||||
|
@ -390,6 +421,7 @@ job_t *job_create();
|
|||
*/
|
||||
job_t *job_get(int id);
|
||||
|
||||
|
||||
/**
|
||||
Return the job with the specified pid.
|
||||
*/
|
||||
|
|
|
@ -2519,7 +2519,7 @@ static void reader_super_highlight_me_plenty( int match_highlight_pos, array_lis
|
|||
int exit_status()
|
||||
{
|
||||
if( is_interactive )
|
||||
return first_job == 0 && data->end_loop;
|
||||
return job_list().empty() && data->end_loop;
|
||||
else
|
||||
return end_loop;
|
||||
}
|
||||
|
@ -2549,7 +2549,8 @@ static void handle_end_loop()
|
|||
}
|
||||
}
|
||||
|
||||
for( j=first_job; j; j=j->next )
|
||||
job_iterator_t jobs;
|
||||
while ((j = jobs.next()))
|
||||
{
|
||||
if( !job_is_completed(j) )
|
||||
{
|
||||
|
@ -2574,7 +2575,8 @@ static void handle_end_loop()
|
|||
in interactive mode. If isatty returns false, it
|
||||
means stdin must have been closed.
|
||||
*/
|
||||
for( j = first_job; j; j=j->next )
|
||||
job_iterator_t jobs;
|
||||
while ((j = jobs.next()))
|
||||
{
|
||||
if( ! job_is_completed( j ) )
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue