mycgi.c

最終更新:2009/12/16

mycgi.c

001: /*
002:  * mycgi.c
003:  * CGI スクリプトを処理する関数
004:  */
005:  
006: #include "apr_general.h"
007: #include "apr_file_io.h"
008: #include "apr_errno.h"
009: #include "apr_tables.h"
010: #include "apr_buckets.h"
011: #include "apr_strings.h"
012: #include "apr_thread_proc.h"
013: #include "mybb.h"
014: #include "mycgi.h"
015: 
016: /*
017:  * ファイル名のディレクトリ部分を返す関数
018:  * '/' がないときは "" を返す。
019:  * ファイル名がヌルの時はヌルを返す。
020:  */
021: 
022: char *get_dir(
023:   char *filename
024:   , apr_pool_t *pool
025: ) {
026:   char *s = NULL;
027:   if (!filename || !pool)
028:     return NULL;
029:     
030:   s = strrchr(filename, '/');
031:   if (s) {
032:     return apr_pstrndup(pool, filename, s-filename);
033:   }
034:   return "";
035: }
036: 
037: /*
038:  * 返り値:
039:  *  1: 成功
040:  *  0: 失敗
041:  */
042: 
043: int invoke_cgi (cgi_ctx *cctx) {
044:   apr_status_t rv;
045:   apr_proc_t proc;
046:   char **args = NULL;
047:   char **env = NULL;
048:   apr_procattr_t *proc_attr = NULL;
049: 
050:   if (!cctx || ! cctx->pool) {
051:     return 0;
052:   }
053:   
054:   /* 引数配列作成 */
055: 
056:   {
057:     args = (char**)apr_palloc(cctx->pool, sizeof(char*)*4);
058:     args[0] = cctx->prog_name;
059:     args[1] = apr_pstrcat(cctx->pool, "-x", get_dir(cctx->script_name, cctx->pool), NULL);
060:     args[2] = cctx->script_name;
061:     args[3] = NULL; /* 最後はヌル */
062:   }
063: 
064:   /* 環境変数配列作成 */
065: 
066:   {
067:     int i=0;
068:     const apr_array_header_t *tarr = apr_table_elts(cctx->env_tab);
069:     const apr_table_entry_t *telts = (const apr_table_entry_t*)tarr->elts;
070:     env = (char**)apr_palloc(cctx->pool, sizeof(char*)*(tarr->nelts+1));
071:     for (i=0; i<tarr->nelts; i++) {
072:       env[i] = apr_pstrcat(cctx->pool, telts[i].key, "=", telts[i].val, NULL);
073:     }
074:     env[i] = NULL; /* 最後はヌル */
075:   }
076: 
077:   /* 子プロセスの属性情報生成 */
078: 
079:   rv=apr_procattr_create(&proc_attr, cctx->pool);
080:   if (APR_SUCCESS != rv) {
081:     goto _FINALLY_;
082:   }
083: 
084:   /* 子プロセスのコマンドタイプ設定 */
085: 
086:   rv=apr_procattr_cmdtype_set(proc_attr, APR_PROGRAM);
087:   if (APR_SUCCESS != rv) {
088:     goto _FINALLY_;
089:   }
090: 
091:   /* 子プロセスのパイプ準備 */
092: 
093:   rv=apr_procattr_io_set(proc_attr, (cctx->clen>0)?APR_FULL_BLOCK:APR_NO_PIPE, APR_FULL_BLOCK, APR_NO_PIPE);
094:   if (APR_SUCCESS != rv) {
095:     goto _FINALLY_;
096:   }
097: 
098:   /* 子プロセスの生成 */
099: 
100:   rv = apr_proc_create(&proc, cctx->prog_name, (const char*const*)args, (const char*const*)env, proc_attr, cctx->pool);
101:   if (APR_SUCCESS!=rv) {
102:     goto _FINALLY_;
103:   }
104: 
105:   /* 子プロセスへの送信 */
106:   
107:   if (cctx->clen >0 && cctx->bbin && proc.in) {
108:     /* cctx->bbin から proc.in へ */
109: /*
110:     apr_bucket_brigade *tmp_bb = apr_brigade_create(cctx->pool, cctx->bbin->bucket_alloc);
111:     if (move_bytes_from_bb (cctx->bbin, cctx->clen, tmp_bb))
112:       write_from_bb_to_fp(tmp_bb, proc.in);
113: */
114:     move_bytes_from_bb_to_fp(cctx->bbin, cctx->clen, proc.in);
115:     apr_file_close(proc.in);
116:   }
117:   
118: 
119:   /* 子プロセスからの受信 */
120: 
121:   if (proc.out) {
122:     /* proc.out から cctx->bbout へ */
123:     #define BUF_SIZE 1024
124:     char buf[BUF_SIZE];
125:     apr_size_t len=0;
126:     while (1) {
127:       if(APR_EOF == apr_file_eof(proc.out)) {
128:         break;
129:       }
130:       len = BUF_SIZE;
131:       if (APR_SUCCESS == apr_file_read(proc.out, buf, &len)) {
132:         apr_brigade_write(cctx->bbout, NULL, NULL, buf, len);
133:       }
134:     }
135:     apr_file_close(proc.out);
136:   }
137:   
138: 
139:   /* 子プロセスの終了待ち */
140: 
141:   {
142:     int exitcode=0;
143:     apr_exit_why_e why;
144:     rv = apr_proc_wait(&proc, &exitcode, &why, APR_WAIT);
145:     if (APR_CHILD_DONE == rv) {
146:       rv = APR_SUCCESS;
147:     }
148:   }
149: 
150:   _FINALLY_:
151:   
152:   if(APR_SUCCESS != rv) {
153:     char error_buf[256];
154:     fprintf(stderr, "ERROR: %s\n", 
155:       apr_strerror(rv, error_buf, sizeof(error_buf)));
156:     return 0;
157:   }
158:   
159:   return 1;
160: }
Copyright (C) KAKU PROJECT (2009)KAKU PROJECT (2009)