Tests about a simple python3 fastcgi runner using libfcgi and the Python-C API.
python
c
wsgi
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

conf.c 3.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. #include "conf.h"
  2. void usage()
  3. {
  4. static const struct option opts[] = PYFCGI_LONG_OPT;
  5. static const char *help[][2] = PYFCGI_OPT_HELP;
  6. size_t i;
  7. dprintf(2, "Usage : %s -e PYMODULE [-E PYFUN] [OPTIONS]\n", PYFCGI_NAME);
  8. dprintf(2, "\nOptions list :\n");
  9. i=0;
  10. while(opts[i].name)
  11. {
  12. dprintf(2, "\t-%c, --%s", opts[i].val, opts[i].name);
  13. switch(opts[i].has_arg)
  14. {
  15. case required_argument:
  16. dprintf(2, "=%s\n",
  17. help[i][1]?help[i][1]:"ARG");
  18. break;
  19. case optional_argument:
  20. dprintf(2, "[=%s]\n",
  21. help[i][1]?help[i][1]:"ARG");
  22. break;
  23. default: //no_argument
  24. dprintf(2, "\n");
  25. }
  26. printf("\t\t%s\n\n", help[i][0]);
  27. i++;
  28. }
  29. dprintf(2, "%s", PYFCGI_HELP_TEXT);
  30. }
  31. void print_version(int fd)
  32. {
  33. char version[16];
  34. pyfcgi_python_version(version);
  35. dprintf(fd, "%s\nPython %s\n", PACKAGE_STRING, version);
  36. }
  37. void default_conf()
  38. {
  39. memset(&PyFCGI_conf, 0, sizeof(pyfcgi_conf_t));
  40. PyFCGI_conf.context.pid = getpid();
  41. PyFCGI_conf.min_wrk = 1;
  42. PyFCGI_conf.max_wrk = 5;
  43. PyFCGI_conf.max_reqs = 1000;
  44. PyFCGI_conf.pep333 = 1;
  45. }
  46. int parse_args(int argc, char *argv[])
  47. {
  48. static const struct option long_options[] = PYFCGI_LONG_OPT;
  49. char ident[] = "pyfcgi[XXXXXXXX]";
  50. int c, opt_i;
  51. while(1)
  52. {
  53. c = getopt_long(argc, argv, PYFCGI_SHORT_OPT, long_options,
  54. &opt_i);
  55. if(c == -1) { break; }
  56. switch(c)
  57. {
  58. case 'v':
  59. print_version(1);
  60. exit(0);
  61. case 'C':
  62. dprintf(2, "Config parser not yet implemented :'(\n");
  63. exit(1);
  64. case 'e':
  65. PyFCGI_conf.py_entrymod = strdup(optarg);
  66. break;
  67. case 'E':
  68. PyFCGI_conf.py_entryfun = strdup(optarg);
  69. break;
  70. case 'A':
  71. PyFCGI_conf.pep333 = 0;
  72. break;
  73. case 'w':
  74. PyFCGI_conf.min_wrk = atoi(optarg);
  75. break;
  76. case 'W':
  77. PyFCGI_conf.max_wrk = atoi(optarg);
  78. break;
  79. case 'm':
  80. PyFCGI_conf.max_reqs = atoi(optarg);
  81. if(PyFCGI_conf.max_reqs < 0)
  82. {
  83. PyFCGI_conf.max_reqs = 0;
  84. }
  85. break;
  86. case 'L':
  87. if(parse_optlog(optarg))
  88. {
  89. exit(1);
  90. }
  91. break;
  92. case 'S':
  93. snprintf(ident+7, 8, "%4d]", PyFCGI_conf.context.pid);
  94. pyfcgi_logger_enable_syslog(ident);
  95. break;
  96. case 'P':
  97. PyFCGI_conf.pidfile = strdup(optarg);
  98. /**@todo create pidfile and put master pid in it */
  99. break;
  100. case 'h':
  101. usage();
  102. exit(0);
  103. default:
  104. usage();
  105. exit(1);
  106. }
  107. }
  108. if(optind < argc)
  109. {
  110. for(opt_i=optind; opt_i<argc; opt_i++)
  111. {
  112. dprintf(2, "Unkown argument '%s'\n", argv[opt_i]);
  113. }
  114. usage();
  115. exit(1);
  116. }
  117. if(!PyFCGI_conf.py_entrymod)
  118. {
  119. dprintf(2, "No python entry module given... exiting\n");
  120. usage();
  121. exit(2);
  122. }
  123. if(!PyFCGI_conf.py_entryfun)
  124. {
  125. PyFCGI_conf.py_entryfun = PYENTRY_DEFAULT_FUN;
  126. }
  127. if(check_entrypoint_import())
  128. {
  129. usage();
  130. exit(3);
  131. }
  132. return 0;
  133. }
  134. int check_entrypoint_import()
  135. {
  136. pid_t pid;
  137. int status;
  138. void *ret;
  139. pid = fork();
  140. if(!pid)
  141. {
  142. pyinit();
  143. ret = (void*)import_entrypoint();
  144. if(!ret)
  145. {
  146. dprintf(2, "Unable to import entrypoint...\n");
  147. exit(1);
  148. }
  149. pyfcgi_log(LOG_DEBUG, "Entrypoint import [OK]");
  150. Py_Exit(0);
  151. }
  152. waitpid(pid, &status, 0);
  153. return WEXITSTATUS(status);
  154. }
  155. int parse_optlog(const char* logspec)
  156. {
  157. char *filename, *filter, *fmt;
  158. int filt;
  159. filename = strdup(logspec); /**@todo check error */
  160. filter = filename;
  161. while(*filter && *filter != ';') { filter++; }
  162. if(*filter)
  163. {
  164. *filter = '\0';
  165. filter++;
  166. }
  167. fmt = filter;
  168. while(*fmt && *fmt != ';') { fmt++; }
  169. if(*fmt)
  170. {
  171. *fmt = '\0';
  172. fmt++;
  173. }
  174. if(!strlen(filter))
  175. {
  176. filt = 0xFF;
  177. }
  178. else
  179. {
  180. filt = strtol(filter, NULL, !strncmp(filter, "0x", 2)?16:10);
  181. }
  182. fmt = strlen(fmt)?fmt:NULL;
  183. if(pyfcgi_logger_add(filename, filt, filt, fmt))
  184. {
  185. return 1;
  186. }
  187. return 0;
  188. }