ucommon

ucommon/shell.h

Go to the documentation of this file.
00001 // Copyright (C) 2006-2010 David Sugar, Tycho Softworks.
00002 //
00003 // This file is part of GNU uCommon C++.
00004 //
00005 // GNU uCommon C++ is free software: you can redistribute it and/or modify
00006 // it under the terms of the GNU Lesser General Public License as published
00007 // by the Free Software Foundation, either version 3 of the License, or
00008 // (at your option) any later version.
00009 //
00010 // GNU uCommon C++ is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU Lesser General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU Lesser General Public License
00016 // along with GNU uCommon C++.  If not, see <http://www.gnu.org/licenses/>.
00017 
00028 #ifndef _UCOMMON_STRING_H_
00029 #include <ucommon/string.h>
00030 #endif
00031 
00032 #ifndef _UCOMMON_MEMORY_H_
00033 #include <ucommon/memory.h>
00034 #endif
00035 
00036 #ifndef _UCOMMON_BUFFER_H_
00037 #include <ucommon/buffer.h>
00038 #endif
00039 
00040 #ifndef _UCOMMON_SHELL_H_
00041 #define _UCOMMON_SHELL_H_
00042 
00043 #ifdef  _MSWINDOWS_
00044 #define INVALID_PID_VALUE   INVALID_HANDLE_VALUE
00045 #else
00046 #define INVALID_PID_VALUE   -1
00047 #endif
00048 
00049 NAMESPACE_UCOMMON
00050 
00058 class __EXPORT shell : public mempager
00059 {
00060 private:
00061     char **_argv;
00062     unsigned _argc;
00063     char *_argv0;
00064     LinkedObject *_syms;
00065 
00066     class __LOCAL args : public OrderedObject
00067     {
00068     public:
00069         char *item;
00070     };
00071 
00072     class __LOCAL syms : public LinkedObject
00073     {
00074     public:
00075         const char *name;
00076         const char *value;
00077     };
00078 
00084     void collapse(LinkedObject *first);
00085 
00089     void set0(char *argv0);
00090 
00091 public:
00095     typedef enum {NOARGS = 0, NOARGUMENT, INVARGUMENT, BADOPTION, OPTION_USED, BAD_VALUE, NUMERIC_SET} errmsg_t;
00096 
00100     typedef enum {NONE = 0, CONSOLE_LOG, USER_LOG, SYSTEM_LOG, SECURITY_LOG} logmode_t;
00101 
00105     typedef enum {FAIL = 0, ERR, WARN, NOTIFY, INFO, DEBUG0} loglevel_t;
00106 
00110     typedef enum {NO_NUMERIC, NUMERIC_PLUS, NUMERIC_DASH, NUMERIC_ALL} numeric_t;
00111 
00115     typedef enum {
00116         PROGRAM_CONFIG, SERVICE_CONFIG, USER_DEFAULTS, SYSTEM_CERTIFICATES,
00117         SYSTEM_KEYS, USER_HOME, SERVICE_DATA, SYSTEM_TEMP, USER_CACHE,
00118         SERVICE_CACHE, USER_DATA, USER_CONFIG, SYSTEM_CFG, SYSTEM_ETC,
00119         SYSTEM_VAR, SYSTEM_PREFIX, SYSTEM_SHARE, PROGRAM_PLUGINS,
00120         PROGRAM_TEMP} path_t;
00121 
00125     typedef bool (*logproc_t)(loglevel_t level, const char *text);
00126 
00130     typedef cpr_service_t   mainproc_t;
00131 
00135     typedef void (*exitproc_t)(void);
00136 
00137 #ifdef  _MSWINDOWS_
00138     typedef HANDLE pid_t;
00139 #else
00140 
00143     typedef int pid_t;
00144 #endif
00145 
00149     typedef enum {RD = BufferProtocol::BUF_RD, WR = BufferProtocol::BUF_WR, RDWR = BufferProtocol::BUF_RDWR} pmode_t;
00150 
00159     class __EXPORT pipeio
00160     {
00161     protected:
00162         friend class shell;
00163 
00167         pipeio();
00168 
00178         int spawn(const char *path, char **argv, pmode_t mode, size_t size = 512, char **env = NULL);
00179 
00184         int wait(void);
00185 
00191         int cancel(void);
00192 
00201         size_t read(void *address, size_t size);
00202 
00211         size_t write(const void *address, size_t size);
00212 
00213         pid_t pid;
00214         fd_t input, output; // input to and output from child process...
00215         int perror, presult;
00216     };
00217 
00224     class __EXPORT iobuf : public BufferProtocol, private pipeio
00225     {
00226     protected:
00227         friend class shell;
00228 
00229         int ioerror;
00230 
00231         virtual int _err(void) const;
00232         virtual void _clear(void);
00233 
00234         virtual size_t _push(const char *address, size_t size);
00235         virtual size_t _pull(char *address, size_t size);
00236 
00237     public:
00243         iobuf(size_t size = 0);
00244 
00255         iobuf(const char *path, char **argv, pmode_t mode, size_t size = 512, char **env = NULL);
00256 
00261         ~iobuf();
00262 
00271         void open(const char *path, char **argv, pmode_t mode, size_t size = 512, char **env = NULL);
00272 
00277         void close(void);
00278 
00283         void cancel(void);
00284     };
00285 
00289     typedef iobuf io_t;
00290 
00294     typedef pipeio *pipe_t;
00295 
00302     static const char *errmsg(errmsg_t id);
00303 
00310     static void errmsg(errmsg_t id, const char *text);
00311 
00318     class __EXPORT errormap
00319     {
00320     public:
00321         inline errormap(errmsg_t id, const char *text)
00322             {shell::errmsg(id, text);};
00323     };
00324 
00332     class __EXPORT Option : public OrderedObject
00333     {
00334     public:
00335         char short_option;
00336         const char *long_option;
00337         const char *uses_option;
00338         const char *help_string;
00339         bool trigger_option;
00340 
00348         Option(char short_option = 0, const char *long_option = NULL, const char *value_type = NULL, const char *help = NULL);
00349 
00350         virtual ~Option();
00351 
00352         static LinkedObject *first(void);
00353 
00358         void disable(void);
00359 
00365         virtual const char *assign(const char *value) = 0;
00366 
00367         static void reset(void);
00368     };
00369 
00377     class __EXPORT flagopt : public Option
00378     {
00379     private:
00380         unsigned counter;
00381         bool single;
00382 
00383         virtual const char *assign(const char *value);
00384 
00385     public:
00386         flagopt(char short_option, const char *long_option = NULL, const char *help = NULL, bool single_use = true);
00387 
00388         inline operator bool()
00389             {return counter > 0;};
00390 
00391         inline bool operator!()
00392             {return counter == 0;};
00393 
00394         inline operator unsigned()
00395             {return counter;};
00396 
00397         inline unsigned operator*()
00398             {return counter;};
00399 
00400         inline void set(unsigned value = 1)
00401             {counter = value;};
00402     };
00403 
00409     class __EXPORT groupopt : public Option
00410     {
00411     private:
00412         virtual const char *assign(const char *value);
00413 
00414     public:
00415         groupopt(const char *help);
00416     };
00417 
00424     class __EXPORT stringopt : public Option
00425     {
00426     private:
00427         bool used;
00428 
00429     protected:
00430         const char *text;
00431 
00432         virtual const char *assign(const char *value);
00433 
00434     public:
00435         stringopt(char short_option, const char *long_option = NULL, const char *help = NULL, const char *type = "text", const char *def_text = NULL);
00436 
00437         inline void set(const char *string)
00438             {text = string;};
00439 
00440         inline operator bool()
00441             {return used;};
00442 
00443         inline bool operator!()
00444             {return !used;};
00445 
00446         inline operator const char *()
00447             {return text;};
00448 
00449         inline const char *operator*()
00450             {return text;};
00451     };
00452 
00459     class __EXPORT charopt : public Option
00460     {
00461     private:
00462         bool used;
00463 
00464     protected:
00465         char code;
00466 
00467         virtual const char *assign(const char *value);
00468 
00469     public:
00470         charopt(char short_option, const char *long_option = NULL, const char *help = NULL, const char *type = "char", char default_code = ' ');
00471 
00472         inline void set(char value)
00473             {code = value;};
00474 
00475         inline operator bool()
00476             {return used;};
00477 
00478         inline bool operator!()
00479             {return !used;};
00480 
00481         inline operator char()
00482             {return code;};
00483 
00484         inline char operator*()
00485             {return code;};
00486     };
00487 
00494     class __EXPORT numericopt : public Option
00495     {
00496     private:
00497         bool used;
00498 
00499     protected:
00500         long number;
00501 
00502         virtual const char *assign(const char *value);
00503 
00504     public:
00505         numericopt(char short_option, const char *long_option = NULL, const char *help = NULL, const char *type = "numeric", long def_value = 0);
00506 
00507         inline void set(long value)
00508             {number = value;};
00509 
00510         inline operator bool()
00511             {return used;};
00512 
00513         inline bool operator!()
00514             {return !used;};
00515 
00516         inline operator long()
00517             {return number;};
00518 
00519         inline long operator*()
00520             {return number;};
00521     };
00522 
00531     class __EXPORT counteropt : public Option
00532     {
00533     private:
00534         bool used;
00535 
00536     protected:
00537         long number;
00538 
00539         virtual const char *assign(const char *value);
00540 
00541     public:
00542         counteropt(char short_option, const char *long_option = NULL, const char *help = NULL, const char *type = "numeric", long def_value = 0);
00543 
00544         inline void set(long value)
00545             {number = value;};
00546 
00547         inline operator bool()
00548             {return used;};
00549 
00550         inline bool operator!()
00551             {return !used;};
00552 
00553         inline operator long()
00554             {return number;};
00555 
00556         inline long operator*()
00557             {return number;};
00558     };
00559 
00567     shell(const char *string, size_t pagesize = 0);
00568 
00577     shell(int argc, char **argv, size_t pagesize = 0);
00578 
00583     shell(size_t pagesize = 0);
00584 
00585     static void setNumeric(numeric_t);
00586 
00587     static long getNumeric(void);
00588 
00592     static void help(void);
00593 
00601     static int system(const char *command, const char **env = NULL);
00602 
00609     static int systemf(const char *format, ...) __PRINTF(1,2);
00610 
00615     static void relocate(const char *argv0);
00616 
00623     static String path(path_t id);
00624 
00629     static String userid(void);
00630 
00636     static String path(path_t id, const char *directory);
00637 
00649     static void bind(const char *name);
00650 
00660     static void rebind(const char *name = NULL);
00661 
00667     char **parse(const char *string);
00668 
00677     void parse(int argc, char **argv);
00678 
00686     const char *getenv(const char *name, const char *value = NULL);
00687 
00694     const char *getsym(const char *name, const char *value = NULL);
00695 
00701     void setsym(const char *name, const char *value);
00702 
00708     bool issym(const char *name);
00709 
00715     char *getargv0(char **argv);
00716 
00724     char **getargv(char **argv);
00725 
00732     void restart(char *argv0, char **argv, char **list);
00733 
00740     inline static char **parse(shell &args, const char *string)
00741         {return args.parse(string);};
00742 
00746     inline const char *argv0() const
00747         {return _argv0;};
00748 
00754     static void errexit(int exitcode, const char *format = NULL, ...) __PRINTF(2, 3);
00755 
00761     static void debug(unsigned level, const char *format, ...) __PRINTF(2, 3);
00762 
00768     static void log(loglevel_t level, const char *format, ...) __PRINTF(2, 3);
00769 
00775     static void security(loglevel_t level, const char *format, ...) __PRINTF(2, 3);
00776 
00784     static void log(const char *name, loglevel_t level = ERR, logmode_t mode = USER_LOG, logproc_t handler = (logproc_t)NULL);
00785 
00790     static size_t printf(const char *format, ...) __PRINTF(1, 2);
00791 
00792     static size_t readln(char *address, size_t size);
00793 
00794     static size_t writes(const char *string);
00795 
00796     static size_t read(String& string);
00797 
00798     inline static size_t write(String& string)
00799         {return writes(string.c_str());};
00800 
00807     static size_t printf(pipe_t pipe, const char *format, ...) __PRINTF(2, 3);
00808 
00816     static size_t readln(pipe_t pipe, char *buffer, size_t size);
00817 
00818     static size_t read(pipe_t pipe, String& string);
00819 
00820     static size_t writes(pipe_t pipe, const char *string);
00821 
00822     inline static size_t write(pipe_t pipe, String& string)
00823         {return writes(pipe, string.c_str());};
00824 
00830     inline unsigned argc(void) const
00831         {return _argc;};
00832 
00839     inline char **argv(void) const
00840         {return _argv;};
00841 
00847     inline const char *operator[](unsigned offset)
00848         {return _argv[offset];};
00849 
00850     static void exiting(exitproc_t);
00851 
00855     void detach(mainproc_t mainentry = (mainproc_t)NULL);
00856 
00860     void restart(void);
00861 
00873     static shell::pid_t spawn(const char *path, char **argv, char **env = NULL, fd_t *stdio = NULL);
00874 
00886     static shell::pipe_t spawn(const char *path, char **argv, pmode_t mode, size_t size = 512, char **env = NULL);
00887 
00896     static void priority(int pri = 1);
00897 
00907     static int  detach(const char *path, char **argv, char **env = NULL, fd_t *stdio = NULL);
00908 
00914     static int wait(shell::pid_t pid);
00915 
00921     static int cancel(shell::pid_t pid);
00922 
00929     static int wait(shell::pipe_t pointer);
00930 
00936     static int cancel(shell::pipe_t pointer);
00937 
00942     inline unsigned operator()(void)
00943         {return _argc;};
00944 
00957     static const char *text(const char *string);
00958 
00968     static const char *texts(const char *singular, const char *plural, unsigned long count);
00969 
00975     static unsigned count(char **argv);
00976 
00977 #ifdef  _MSWINDOWS_
00978 
00979     static inline fd_t input(void)
00980         {return GetStdHandle(STD_INPUT_HANDLE);};
00981 
00982     static inline fd_t output(void)
00983         {return GetStdHandle(STD_OUTPUT_HANDLE);};
00984 
00985     static inline fd_t error(void)
00986         {return GetStdHandle(STD_ERROR_HANDLE);};
00987 
00988 #else
00989     static inline fd_t input(void)
00990         {return 0;};
00991 
00992     static inline fd_t output(void)
00993         {return 1;};
00994 
00995     static inline fd_t error(void)
00996         {return 2;};
00997 #endif
00998 };
00999 
01003 typedef shell shell_t;
01004 
01008 #undef  _TEXT
01009 #undef  _STR
01010 
01018 inline  const char *_TEXT(const char *s)
01019     {return shell::text(s);}
01020 
01021 inline const char *_STR(String& s)
01022     {return *s;}
01023 
01024 END_NAMESPACE
01025 
01026 #endif