kpdetach.c

最終更新:2009/12/16

kpdetach.c

001: /* kpdetach.c
002:  * プロセス処理のサンプル
003:  * ・外部プログラムのプロセスをデタッチ(detach)する。
004:  * ・子プロセスには現在の環境変数が引き継がれる。
005:  * ・子プロセスのプロセスIDを表示する。
006:  * ・Unix ではデーモン化、Windows ではコンソールなしに起動する。
007:  * ・デタッチした子プロセスの終了は、Windows ではタスクマネージャなどを使う。
008:  */
009: 
010: #define USAGE "Usage: kpdetach <prog_name> <args>"
011: 
012: #include "apr_general.h"
013: #include "apr_file_io.h"
014: #include "apr_errno.h"
015: #include "apr_env.h"
016: #include "apr_strings.h"
017: #include "apr_thread_proc.h"
018: 
019: #include "mystab.h"
020: 
021: int apr_my_main (
022:   int ac, char **av
023:   , apr_file_t * astdin
024:   , apr_file_t * astdout
025:   , apr_file_t * astderr
026:   , apr_pool_t * pool
027: ) {
028: 
029:   apr_status_t rv=APR_SUCCESS;
030:   
031:   char *prog_name = NULL;
032:   char **args = NULL;
033:   
034:   apr_proc_t proc;
035:   apr_pool_t *pool2 = NULL;
036:   
037:   apr_procattr_t *proc_attr = NULL;
038:   
039:   if (ac < 2) {
040:     apr_file_printf(astderr, "%s\n", USAGE);
041:     goto _FINALLY_;
042:   }
043: 
044:   /* 子プロセスが実行するコマンド */
045: 
046:   prog_name = av[1];
047: 
048:   /* 子プロセスの実行するコマンドへの引数配列の準備 */
049: 
050:   if (ac > 1) {
051:     int i;
052:     args = (char**)apr_palloc(pool, sizeof(char*)*(ac));
053:     for (i=0; i<ac-1; i++) { /* args[0] には av[1] が入る */
054:       args[i] = av[i+1];
055:     }
056:     args[i]=NULL; /* 最後はヌル */
057:     
058:   }
059: 
060:   /* 子プロセス用引数配列の確認 */
061: 
062:   if (args) {
063:     char **x=args;
064:     printf("#prog_name=[%s]\n", prog_name);
065:     for (; *x; x++) {
066:       printf("#args[%d]=[%s]\n", x-args, *x);
067:     }
068:   }
069:   
070:   /* 子プロセス用メモリプール生成 */
071: 
072:   rv=apr_pool_create(&pool2, NULL);
073:   if (APR_SUCCESS != rv) {
074:     goto _FINALLY_;
075:   }
076: 
077:   /* 子プロセスの属性情報生成 */
078: 
079:   rv=apr_procattr_create(&proc_attr, pool);
080:   if (APR_SUCCESS != rv) {
081:     goto _FINALLY_;
082:   }
083: 
084:   /* 子プロセスのコマンドタイプ設定 */
085: 
086:   rv=apr_procattr_cmdtype_set(proc_attr, APR_PROGRAM_ENV);
087:   if (APR_SUCCESS != rv) {
088:     goto _FINALLY_;
089:   }
090: 
091:   /* 子プロセスのデタッチ属性をセット(デーモン化) */
092:   apr_procattr_detach_set(proc_attr, TRUE);
093: 
094:   /* 子プロセスのパイプ準備 */
095: 
096:   rv=apr_procattr_io_set(proc_attr, APR_NO_PIPE, APR_NO_PIPE, APR_NO_PIPE);
097:   if (APR_SUCCESS != rv) {
098:     goto _FINALLY_;
099:   }
100: 
101:   /* 子プロセスの生成 */
102: 
103:   rv = apr_proc_create(&proc, prog_name, (const char*const*)args, NULL, proc_attr, pool2);
104:   if (APR_SUCCESS!=rv) {
105:     goto _FINALLY_;
106:   }
107: 
108:   /* 子プロセスのPID */
109:   apr_file_printf(astdout, "PID=[%d]\n", proc.pid);
110:   
111:   _FINALLY_:
112: 
113:   /* 子プロセス用メモリプールの解放 */
114:   
115:   if (pool2) {
116:     apr_pool_destroy(pool2);
117:     pool2 = NULL;
118:   }
119: 
120:   if (APR_SUCCESS != rv) {
121:     char error_buf[64];
122:     apr_file_printf(astderr, 
123:       "ERROR: %s\n", apr_strerror(rv, error_buf, sizeof(error_buf)));
124: 
125:     apr_file_printf(astderr, "failed!\n");
126:     return 1; /* 異常終了 */
127: 
128:   }
129: 
130:   apr_file_printf(astdout, "\ndone.\n");
131: 
132:   return 0; /* 正常終了 */
133:   
134: 
135: } /* end of main */
Copyright (C) KAKU PROJECT (2009)KAKU PROJECT (2009)