📄 a_ls.cpp
字号:
/* Copyright is licensed under GNU LGPL. by I.J.Wang 2005 Simulate utility ls -l Build: make a_ls Bug: if directory in the pathname can't be 'chdir', a_ls fails.*/#include "../src/wy_uty.h"#include "../src/wyregfile.h"#include "../src/wy_dirfile.h"#include "../src/wydate.h"#include "../src/wy_atdestroy.h"#include <pwd.h>#include <sys/types.h>#include <grp.h>// Get the time zone string//static const WyStr& tz_string(void){static const WyStr tzstr(Wy::local_tzname()); return tzstr;}// Convert mode_t to text string (e.g. "-rwx-rw-r--")//static WyStr fmode_str(const mode_t m) throw(WyStr::Reply){ WyStr str(10,'-'); if(S_ISREG(m)) { } else if(S_ISDIR(m)) { str[0]='d'; } else if(S_ISCHR(m)) { str[0]='c'; } else if(S_ISBLK(m)) { str[0]='b'; } else if(S_ISFIFO(m)) { str[0]='f'; } else if(S_ISLNK(m)) { str[0]='l'; } else if(S_ISSOCK(m)) { str[0]='s'; } else { str[0]='?'; } if(m&S_IRUSR) { str[1]='r'; } if(m&S_IWUSR) { str[2]='w'; } if(m&S_IXUSR) { str[3]='x'; } if(m&S_ISUID) { str[3]='s'; } if(m&S_IRGRP) { str[4]='r'; } if(m&S_IWGRP) { str[5]='w'; } if(m&S_IXGRP) { str[6]='x'; } if(m&S_ISGID) { str[6]='s'; } if(m&S_IROTH) { str[7]='r'; } if(m&S_IWOTH) { str[8]='w'; } if(m&S_IXOTH) { str[9]='x'; } if(m&S_ISVTX) { str[9]='t'; } return(str);};// [Syn] Append blanks to the right of str, so the length of str// is at least flen (left alignment)//static WyStr& fill_end(size_t flen, WyStr& str){ if(str.size()<flen) { WyRet r; if((r=str.append(flen-str.size(),' '))!=Ok) { WY_THROW( WyStr::Reply(r) ); } } return str;};// [Syn] Insert blanks to the left of str, so the length of str// is at least flen (right alignment)//static WyStr& fill_begin(size_t flen, WyStr& str){ if(str.size()<flen) { WyRet r; if((r=str.insert(0,flen-str.size(),' '))!=Ok) { WY_THROW( WyStr::Reply(r) ); } } return str;};// ls -l fname//WyRet ls_file_l(const char* fname)try { WyRet r; WyFileStat stt; if((r=Wy::stat(fname,stt))!=Ok) { WY_RETURN(r); } // print mode_t Wy::cout << fmode_str(stt.sf_mode()) << ' '; // print number of links, left alignment { WyStr str; if((r=Wy::_mkstr(str,stt.sf_nlink(),int(10)))!=Ok) { WY_RETURN(r); } Wy::cout << fill_end(4,str); } // print uid, left alignment { WyStr u_name; const struct ::passwd *p_pwd=::getpwuid(stt.sf_uid()); if(p_pwd==NULL) { if((r=Wy::_mkstr(u_name,stt.sf_uid(),int(10)))!=Ok) { WY_RETURN(r); } } else { if((r=u_name.reset(p_pwd->pw_name))!=Ok) { WY_RETURN(r); } } Wy::cout << fill_end(5,u_name); } // print uid, left alignment { WyStr g_name; const struct ::group *p_grp=::getgrgid(stt.sf_gid()); if(p_grp==NULL) { if((r=Wy::_mkstr(g_name,stt.sf_gid(),int(10)))!=Ok) { WY_RETURN(r); } } else { if((r=g_name.reset(p_grp->gr_name))!=Ok) { WY_RETURN(r); } } Wy::cout << fill_end(5,g_name); } // print file size, right alignment { WyStr tstr; if((r=Wy::_mkstr(tstr,stt.sf_size(),10))!=Ok) { WY_RETURN(r); } Wy::cout << fill_begin(10,tstr); } // print date, timezone string stripped try { WyStr dstr( Wy::wrd( WyDate(tz_string(), WyTimeSpec(stt.sf_mtime(),0)) ) ); size_t fidx; if(dstr.find(&fidx,' ')==false) { WY_TERMINATE(""); } Wy::cout << ' ' << WyStr(dstr.cseg(0,fidx)); } catch(const WyRet& e) { WY_RETURN(e); }; // print file name and LF Wy::cout << ' ' << fname << "\n"; return(Ok);}catch(const WyStr::Reply& e) { WY_RETURN(e);}catch(const WyByteFlow::Reply& e) { WY_RETURN(e);}catch(const WyRet& e) { WY_THROW( WyRet(e) );}catch(...) { WY_TERMINATE("unexpected throw type");};WyRet ls_dir(const char* dirname)try { WyRet r; Wy_DirFile dfile(dirname); WyDirEnt dent; // loop each directory entry and call ls_file_l // while((r=dfile.read(dent))==Ok) { if(dent.is_default()) { break; // eof } if((r=ls_file_l(dent.dt_name()))!=Ok) { return(r); } } return(Ok);}catch(const Wy_DirFile::Reply& e) { WY_RETURN(e);}catch(const WyRet& e) { throw;}catch(...) { WY_TERMINATE("unexpected throw type");};int main(int argc, char* argv[])try { static const char *cmd_syntax= " List directory contents\n" " [Usage]$a_ls [-h] {pathname}\n" ; // Command-line option process // { const char optstr[]="h"; int optch; while((optch=::getopt(argc,argv,optstr))!=-1) { switch(optch) { case 'h': Wy::cout << cmd_syntax; return(0); case ':': // missing parameter case '?': // unknown option Wy::cerr << "parameter error\n"; Wy::cerr << cmd_syntax; return(-1); default: Wy::cerr << "parameter fault\n"; return(-1); } } } WyRet r; if(optind>=argc) { // simulate "ls -l" if no non-option command argument if((r=ls_dir("."))!=Ok) { throw(r); } } else { // loop each non-option command argument for( ; optind<argc; optind++) { const char* fname(argv[optind]); WyFileStat stt; if((r=Wy::stat(fname,stt))!=Ok) { WY_THROW(r); } if(stt.is_dir()) { WyStr predir; if((r=Wy::getcwd(predir))!=Ok) { WY_THROW(r); } if((r=Wy::chdir(fname))!=Ok) { WY_THROW(r); } Wy_AtDestroy<WyRet,const WyStr&> rrid(Wy::chdir,predir); if((r=ls_dir("."))!=Ok) { throw(r); } } else { if((r=ls_file_l(fname))!=Ok) { throw(r); } } } } return(0);}catch(const WyRet& e) { Wy::cerr << Wy::wrd(e) << '\n'; return(e->c_repcode());}catch(...) { Wy::cerr << "main caught(...)\n"; return(-1);};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -