00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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, SERVICE_CONTROL,
00117 USER_HOME = USER_DEFAULTS + 3, 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;
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
00637 static String path(path_t id, const char *directory);
00638
00644 static String path(String& prefix, const char *directory);
00645
00657 static void bind(const char *name);
00658
00668 static void rebind(const char *name = NULL);
00669
00675 char **parse(const char *string);
00676
00685 void parse(int argc, char **argv);
00686
00694 const char *getenv(const char *name, const char *value = NULL);
00695
00702 const char *getsym(const char *name, const char *value = NULL);
00703
00709 void setsym(const char *name, const char *value);
00710
00716 bool issym(const char *name);
00717
00723 char *getargv0(char **argv);
00724
00732 char **getargv(char **argv);
00733
00740 void restart(char *argv0, char **argv, char **list);
00741
00748 inline static char **parse(shell &args, const char *string)
00749 {return args.parse(string);};
00750
00754 inline const char *argv0() const
00755 {return _argv0;};
00756
00762 static void errexit(int exitcode, const char *format = NULL, ...) __PRINTF(2, 3);
00763
00769 static void debug(unsigned level, const char *format, ...) __PRINTF(2, 3);
00770
00776 static void log(loglevel_t level, const char *format, ...) __PRINTF(2, 3);
00777
00783 static void security(loglevel_t level, const char *format, ...) __PRINTF(2, 3);
00784
00792 static void log(const char *name, loglevel_t level = ERR, logmode_t mode = USER_LOG, logproc_t handler = (logproc_t)NULL);
00793
00798 static size_t printf(const char *format, ...) __PRINTF(1, 2);
00799
00800 static size_t readln(char *address, size_t size);
00801
00802 static size_t writes(const char *string);
00803
00804 static size_t read(String& string);
00805
00806 inline static size_t write(String& string)
00807 {return writes(string.c_str());};
00808
00815 static size_t printf(pipe_t pipe, const char *format, ...) __PRINTF(2, 3);
00816
00824 static size_t readln(pipe_t pipe, char *buffer, size_t size);
00825
00826 static size_t read(pipe_t pipe, String& string);
00827
00828 static size_t writes(pipe_t pipe, const char *string);
00829
00830 inline static size_t write(pipe_t pipe, String& string)
00831 {return writes(pipe, string.c_str());};
00832
00838 inline unsigned argc(void) const
00839 {return _argc;};
00840
00847 inline char **argv(void) const
00848 {return _argv;};
00849
00855 inline const char *operator[](unsigned offset)
00856 {return _argv[offset];};
00857
00858 static void exiting(exitproc_t);
00859
00863 void detach(mainproc_t mainentry = (mainproc_t)NULL);
00864
00868 void restart(void);
00869
00881 static shell::pid_t spawn(const char *path, char **argv, char **env = NULL, fd_t *stdio = NULL);
00882
00894 static shell::pipe_t spawn(const char *path, char **argv, pmode_t mode, size_t size = 512, char **env = NULL);
00895
00904 static void priority(int pri = 1);
00905
00915 static int detach(const char *path, char **argv, char **env = NULL, fd_t *stdio = NULL);
00916
00922 static int wait(shell::pid_t pid);
00923
00929 static int cancel(shell::pid_t pid);
00930
00937 static int wait(shell::pipe_t pointer);
00938
00944 static int cancel(shell::pipe_t pointer);
00945
00950 inline unsigned operator()(void)
00951 {return _argc;};
00952
00965 static const char *text(const char *string);
00966
00976 static const char *texts(const char *singular, const char *plural, unsigned long count);
00977
00983 static unsigned count(char **argv);
00984
00985 #ifdef _MSWINDOWS_
00986
00987 static inline fd_t input(void)
00988 {return GetStdHandle(STD_INPUT_HANDLE);};
00989
00990 static inline fd_t output(void)
00991 {return GetStdHandle(STD_OUTPUT_HANDLE);};
00992
00993 static inline fd_t error(void)
00994 {return GetStdHandle(STD_ERROR_HANDLE);};
00995
00996 #else
00997 static inline fd_t input(void)
00998 {return 0;};
00999
01000 static inline fd_t output(void)
01001 {return 1;};
01002
01003 static inline fd_t error(void)
01004 {return 2;};
01005 #endif
01006 };
01007
01011 typedef shell shell_t;
01012
01016 #undef _TEXT
01017 #undef _STR
01018
01026 inline const char *_TEXT(const char *s)
01027 {return shell::text(s);}
01028
01029 inline const char *_STR(String& s)
01030 {return *s;}
01031
01032 END_NAMESPACE
01033
01034 #endif