CmdExec::CmdExec(FileAccess *s,LocalDirectory *c)
: SessionJob(s?s:new DummyProto)
{
init(c);
}
该构造函数有两个参数s和c。
首先用s初始化SessionJob,在执行方法init(c)。
SessionJob(FileAccess *s)是CmdExec的基类SessionJob的普通构造函数,它会用s初始化数据成员session。
session是FileAccessRef类型的。
类FileAccessRef的一般构造函数FileAccessRef(FileAccess *p)会用p初始化父类SMTaskRef<FileAccess>。
SMTaskRef<T>(T *p)一般构造函数会用p作为参数,给父类Ref<T>进一步处理,Ref<T>(SMTask::MakeRef(p))。
Ref<T>(SMTask::MakeRef(p))分两个部分,先执行SMTask::MakeRef(p),然后Ref<T>(T *p)。
SMTask::MakeRef(p)是做什么的?
先来看看MakeRef是什么?
template<typename T> static T *MakeRef(T *task) { _MakeRef(task); return task; }
MakeRef先通过_MakeRef(task)处理task,然后返回task。
_MakeRef是什么?
static SMTask *_MakeRef(SMTask *task) { if(task) task->IncRefCount(); return task; }
如果task不为NULL,就执行task->IncRefCount(),让成员ref_count增加,然后返回task。
回到一开始,将p换成s,此时s->ref_count、已经增加了1。
接下来Ref<T>(T *s)。
Ref<T>(T *p) { ptr=p; }
将数据成员ptr用s来初始化。
接下去要看init(c)作甚?
先让next指向chain表,然后将chain指针指向this。
实际上是将新构造出的CmdExec对象前插到chain表中。
chain指向this。background、interactive、top_level、auto_terminate_in_bg、feeder_called、partial_cmd、remote_completion、csh_history、verify_path_cached设为false;将show_status、fed_at_finish、verify_host、verify_path设为true,feeder、used_aliases、alias_field、default_output、prev_exit_code、exit_code、failed_exit_code、long_running、start_time、redirections、queue_feeder、max_waiting、saved_session、设为0;
condition设为COND_ANY,last_bg设为-1,builtin设为BUILTIN_NONE;
cwd设为c;如果cwd是0,就进行SaveCWD();
void CmdExec::SaveCWD()
{
if(!cwd)
cwd=new LocalDirectory;
cwd->SetFromCWD();
if(cwd_owner==0)
cwd_owner=this;
}
如果cwd是0,给cwd分配一个空间,执行cwd->SetFromCWD(),
void LocalDirectory::SetFromCWD()
{
Unset();
fd=open(".",O_RDONLY|O_DIRECTORY);
name.set_allocated(xgetcwd());
}