Changeset 240:f1aec5ab5c31 for uwsgi.c

Show
Ignore:
Timestamp:
03/01/10 14:02:36 (5 months ago)
Author:
roberto@…
Branch:
default
Message:

useful XML support, first commit of uwsgiconfig.py

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • uwsgi.c

    r239 r240  
    3030 
    3131 
    32  
    33 #ifndef UNBIT 
    34  
    35 #ifndef ROCK_SOLID 
    36 #include <libxml/parser.h> 
    37 #include <libxml/tree.h> 
    38 #endif 
    39  
    40 #endif 
    41  
    42  
    4332#include "uwsgi.h" 
    4433 
     
    5241static char *h_sep = ": "; 
    5342static const char *http_protocol = "HTTP/1.1"; 
    54 #ifndef ROCK_SOLID 
    5543static const char *app_slash = "/"; 
    56 #endif 
    5744 
    5845extern char **environ; 
     
    8673 
    8774 
    88 #ifdef ROCK_SOLID 
    8975struct uwsgi_app *wi; 
    90 #endif 
    9176 
    9277void warn_pipe () { 
     
    9681void gracefully_kill () { 
    9782        fprintf (stderr, "Gracefully killing worker %d...\n", uwsgi.mypid); 
    98         if (uwsgi.workers[uwsgi.mywid].in_request) { 
     83        if (UWSGI_IS_IN_REQUEST) { 
    9984                uwsgi.workers[uwsgi.mywid].manage_next_request = 0; 
    10085        } 
     
    172157 
    173158#ifndef UNBIT 
    174 #ifndef ROCK_SOLID 
    175159void stats () { 
    176160        struct uwsgi_app *ua = NULL; 
     
    188172} 
    189173#endif 
    190 #endif 
    191174 
    192175void internal_server_error (int fd, char *message) { 
    193176#ifndef UNBIT 
    194 #ifndef ROCK_SOLID 
    195177        if (uwsgi.options[UWSGI_OPTION_CGI_MODE] == 0) { 
    196178#endif 
    197 #endif 
    198179                wsgi_req.headers_size = write (fd, "HTTP/1.1 500 Internal Server Error\r\nContent-type: text/html\r\n\r\n", 63); 
    199180#ifndef UNBIT 
    200 #ifndef ROCK_SOLID 
    201181        } 
    202182        else { 
    203183                wsgi_req.headers_size = write (fd, "Status: 500 Internal Server Error\r\nContent-type: text/html\r\n\r\n", 62); 
    204184        } 
    205 #endif 
    206185        wsgi_req.header_cnt = 2; 
    207186#endif 
     
    281260 
    282261#ifndef UNBIT 
    283 #ifndef ROCK_SOLID 
    284262        if (uwsgi.options[UWSGI_OPTION_CGI_MODE] == 0) { 
    285263                base = 4; 
    286 #endif 
    287264#endif 
    288265 
     
    310287                uwsgi.hvec[3].iov_len = NL_SIZE; 
    311288#ifndef UNBIT 
    312 #ifndef ROCK_SOLID 
    313289        } 
    314290        else { 
     
    329305        } 
    330306#endif 
    331 #endif 
    332307 
    333308 
     
    428403} 
    429404 
    430 #ifndef ROCK_SOLID 
     405#ifdef UWSGI_SENDFILE 
    431406PyObject *py_uwsgi_sendfile (PyObject * self, PyObject * args) { 
    432407 
     
    458433}; 
    459434 
    460 #ifndef ROCK_SOLID 
     435#ifdef UWSGI_SENDFILE 
    461436PyMethodDef uwsgi_sendfile_method[] = { {"uwsgi_sendfile", py_uwsgi_sendfile, METH_VARARGS, ""} 
    462437}; 
     
    503478        int ret; 
    504479 
    505 #ifndef ROCK_SOLID 
    506480        int rlen; 
    507 #ifdef SCTP 
     481 
     482#ifdef UWSGI_SCTP 
    508483        int i_am_sctp = 0; 
    509484        struct sctp_sndrcvinfo sctp_ss; 
     
    515490        socklen_t udp_len; 
    516491        char udp_client_addr[16]; 
    517 #endif 
     492 
    518493        pid_t pid; 
    519494        int no_server = 0; 
    520495 
    521496#ifndef UNBIT 
    522         char *socket_name = NULL; 
    523 #ifndef ROCK_SOLID 
    524497        FILE *pidfile; 
    525 #endif 
    526498#endif 
    527499 
     
    530502 
    531503        char *cwd; 
    532         char *binary_path; 
    533504        int ready_to_reload = 0; 
    534505        int ready_to_die = 0; 
     
    536507        char *env_reloads ; 
    537508        unsigned int reloads = 0; 
    538         int is_a_reload = 0; 
    539509        char env_reload_buf[11]; 
    540510 
    541511        char *buffer; 
    542  
    543         struct rlimit rl; 
    544512 
    545513#ifdef UNBIT 
     
    585553        } 
    586554 
    587 #ifndef ROCK_SOLID 
    588555        uwsgi.wsgi_cnt = 1; 
    589556        uwsgi.default_app = -1; 
    590 #endif 
     557 
    591558        uwsgi.buffer_size = 4096; 
    592559        uwsgi.numproc = 1; 
     
    595562#endif 
    596563 
    597         uwsgi.maxworkers = 64; 
    598  
    599564        uwsgi.max_vars = MAX_VARS; 
    600565        uwsgi.vec_size = 4 + 1 + (4 * MAX_VARS); 
     
    603568        uwsgi.options[UWSGI_OPTION_LOGGING] = 1; 
    604569 
    605 #ifndef ROCK_SOLID 
    606         uwsgi.i_have_gil = 1; 
    607 #endif 
    608  
    609 #ifndef UNBIT 
    610 #ifndef ROCK_SOLID 
     570#ifndef UNBIT 
    611571        int option_index = 0; 
    612572        struct option long_options[] = { 
     
    652612                {"udp", required_argument, 0, LONG_ARGS_UDP}, 
    653613                {"check-interval", required_argument, 0, LONG_ARGS_CHECK_INTERVAL}, 
     614                {"erlang", required_argument, 0, LONG_ARGS_ERLANG}, 
    654615                {0, 0, 0, 0} 
    655616        }; 
    656617#endif 
    657 #endif 
    658618 
    659619 
     
    662622        setlinebuf (stdout); 
    663623 
    664         rl.rlim_cur = 0; 
    665         rl.rlim_max = 0; 
     624        uwsgi.rl.rlim_cur = 0; 
     625        uwsgi.rl.rlim_max = 0; 
    666626 
    667627        cwd = uwsgi_get_cwd (); 
    668         binary_path = malloc (strlen (argv[0]) + 1); 
    669         if (binary_path == NULL) { 
     628        uwsgi.binary_path = malloc (strlen (argv[0]) + 1); 
     629        if (uwsgi.binary_path == NULL) { 
    670630                perror ("malloc()"); 
    671631                exit (1); 
    672632        } 
    673         strcpy (binary_path, argv[0]); 
     633        strcpy (uwsgi.binary_path, argv[0]); 
    674634 
    675635        env_reloads = getenv("UWSGI_RELOADS"); 
     
    688648        } 
    689649        else { 
    690                 fprintf(stderr,"setting UWSGI_RELOADS\n"); 
    691650                if (setenv("UWSGI_RELOADS","0", 1)) { 
    692651                        perror("setenv()"); 
     
    698657                if (socket_type == SOCK_STREAM && reloads > 0) {  
    699658                        fprintf (stderr, "...fd 3 is a socket, i suppose this is a graceful reload of uWSGI, i will try to do my best...\n"); 
    700                         is_a_reload = 1; 
     659                        uwsgi.is_a_reload = 1; 
    701660#ifdef UNBIT 
    702661                        /* discard the 3'th fd as we will use the fd 0 */ 
     
    709668 
    710669#ifndef UNBIT 
    711 #ifndef ROCK_SOLID 
    712670        while ((i = getopt_long (argc, argv, "s:p:t:x:d:l:O:v:b:mcaCTPiMhrR:z:w:j:H:A:Q:L", long_options, &option_index)) != -1) { 
    713671#else 
    714         while ((i = getopt (argc, argv, "s:p:t:d:l:v:b:aCMhrR:z:j:H:A:L")) != -1) { 
    715 #endif 
     672        while ((i = getopt (argc, argv, "p:t:mTPiv:b:rMR:Sz:w:C:j:H:A:EQ:L")) != -1) { 
     673#endif 
     674                manage_opt(i, optarg); 
     675 
     676        } 
     677 
     678#ifdef UWSGI_XML 
     679        if (uwsgi.xml_config != NULL) { 
     680                uwsgi_xml_config (&wsgi_req, long_options); 
     681        } 
     682#endif 
     683 
     684#ifndef UNBIT 
     685#ifndef ROCK_SOLID 
     686        if (uwsgi.options[UWSGI_OPTION_CGI_MODE] == 0) { 
     687#endif 
     688#endif 
     689                if (uwsgi.test_module == NULL) { 
     690                        fprintf (stderr, "*** Starting uWSGI (%dbit) on [%.*s] ***\n", (int) (sizeof (void *)) * 8, 24, ctime ((const time_t *) &uwsgi.start_tv.tv_sec)); 
     691                } 
     692#ifndef UNBIT 
     693        } 
     694        else { 
     695                fprintf (stderr, "*** Starting uWSGI (CGI mode) (%dbit) on [%.*s] ***\n", (int) (sizeof (void *)) * 8, 24, ctime ((const time_t *) &uwsgi.start_tv.tv_sec)); 
     696        } 
     697#endif 
     698 
     699#ifdef __BIG_ENDIAN__ 
     700        fprintf (stderr, "*** big endian arch detected ***\n"); 
     701#endif 
     702 
     703#ifdef PYTHREE 
     704        fprintf (stderr, "*** Warning Python3.x support is experimental, do not use it in production environment ***\n"); 
     705#endif 
     706 
     707        fprintf (stderr, "Python version: %s\n", Py_GetVersion ()); 
     708 
     709#ifndef UNBIT 
     710        if (!getuid ()) { 
     711                fprintf (stderr, "uWSGI running as root, you can use --uid/--gid/--chroot options\n"); 
     712                if (uwsgi.chroot) { 
     713                        fprintf (stderr, "chroot() to %s\n", uwsgi.chroot); 
     714                        if (chroot (uwsgi.chroot)) { 
     715                                perror ("chroot()"); 
     716                                exit (1); 
     717                        } 
     718#ifdef __linux__ 
     719                        if (uwsgi.options[UWSGI_OPTION_MEMORY_DEBUG]) { 
     720                                fprintf (stderr, "*** Warning, on linux system you have to bind-mount the /proc fs in your chroot to get memory debug/report.\n"); 
     721                        } 
     722#endif 
     723                } 
     724                if (uwsgi.gid) { 
     725                        fprintf (stderr, "setgid() to %d\n", uwsgi.gid); 
     726                        if (setgid (uwsgi.gid)) { 
     727                                perror ("setgid()"); 
     728                                exit (1); 
     729                        } 
     730                } 
     731                if (uwsgi.uid) { 
     732                        fprintf (stderr, "setuid() to %d\n", uwsgi.uid); 
     733                        if (setuid (uwsgi.uid)) { 
     734                                perror ("setuid()"); 
     735                                exit (1); 
     736                        } 
     737                } 
     738 
     739                if (!getuid()) { 
     740                        fprintf(stderr," *** WARNING: you are running uWSGI as root !!! (use the --uid flag) *** \n"); 
     741                } 
     742        } 
     743        else { 
     744                if (uwsgi.chroot) { 
     745                        fprintf (stderr, "cannot chroot() as non-root user\n"); 
     746                        exit (1); 
     747                } 
     748                if (uwsgi.gid) { 
     749                        fprintf (stderr, "cannot setgid() as non-root user\n"); 
     750                        exit (1); 
     751                } 
     752                if (uwsgi.uid) { 
     753                        fprintf (stderr, "cannot setuid() as non-root user\n"); 
     754                        exit (1); 
     755                } 
     756        } 
     757 
     758         
     759 
     760#endif 
     761 
     762#ifndef UNBIT 
     763        if (uwsgi.rl.rlim_max > 0) { 
     764                fprintf (stderr, "limiting address space of processes...\n"); 
     765                if (setrlimit (RLIMIT_AS, &uwsgi.rl)) { 
     766                        perror ("setrlimit()"); 
     767                } 
     768        } 
     769#endif 
     770 
     771        if (!getrlimit (RLIMIT_AS, &uwsgi.rl)) { 
     772#ifndef UNBIT 
     773                // check for overflow 
     774                if ((sizeof (void *) == 4 && (uint32_t) uwsgi.rl.rlim_max < UINT32_MAX) || (sizeof (void *) == 8 && (uint64_t) uwsgi.rl.rlim_max < UINT64_MAX)) { 
     775#endif 
     776                        fprintf (stderr, "your process address space limit is %lld bytes (%lld MB)\n", (long long) uwsgi.rl.rlim_max, (long long) uwsgi.rl.rlim_max / 1024 / 1024); 
     777#ifndef UNBIT 
     778                } 
     779#endif 
     780        } 
     781 
     782        uwsgi.page_size = getpagesize (); 
     783        fprintf (stderr, "your memory page size is %d bytes\n", uwsgi.page_size); 
     784 
     785#ifndef UNBIT 
     786        fprintf (stderr, "your server socket listen backlog is limited to %d connections\n", uwsgi.listen_queue); 
     787#endif 
     788 
     789        if (uwsgi.synclog) { 
     790                fprintf (stderr, "allocating a memory page for synced logging.\n"); 
     791                uwsgi.sync_page = malloc (uwsgi.page_size); 
     792                if (!uwsgi.sync_page) { 
     793                        perror ("malloc()"); 
     794                        exit (1); 
     795                } 
     796        } 
     797 
     798        if (uwsgi.pyhome != NULL) { 
     799                fprintf (stderr, "Setting PythonHome to %s...\n", uwsgi.pyhome); 
     800#ifdef PYTHREE 
     801                wchar_t *wpyhome; 
     802                wpyhome = malloc ((sizeof (wchar_t) * strlen (uwsgi.pyhome)) + 2); 
     803                if (!wpyhome) { 
     804                        perror ("malloc()"); 
     805                        exit (1); 
     806                } 
     807                mbstowcs (wpyhome, uwsgi.pyhome, strlen (uwsgi.pyhome)); 
     808                Py_SetPythonHome (wpyhome); 
     809                free (wpyhome); 
    716810#else 
    717         while ((i = getopt (argc, argv, "p:t:mTPiv:b:rMR:Sz:w:C:j:H:A:EQ:L")) != -1) { 
    718 #endif 
     811                Py_SetPythonHome (uwsgi.pyhome); 
     812#endif 
     813        } 
     814 
     815 
     816 
     817 
     818#ifdef PYTHREE 
     819        wchar_t pname[6]; 
     820        mbstowcs (pname, "uWSGI", 6); 
     821        Py_SetProgramName (pname); 
     822#else 
     823        Py_SetProgramName ("uWSGI"); 
     824#endif 
     825 
     826 
     827        Py_Initialize (); 
     828 
     829        pyargv[0] = "uwsgi"; 
     830 
     831        if (uwsgi.pyargv != NULL) { 
     832                char *ap; 
     833                while ((ap = strsep (&uwsgi.pyargv, " \t")) != NULL) { 
     834                        if (*ap != '\0') { 
     835                                pyargv[pyargc] = ap; 
     836                                pyargc++; 
     837                        } 
     838                        if (pyargc + 1 > MAX_PYARGV) 
     839                                break; 
     840                } 
     841        } 
     842 
     843        PySys_SetArgv (pyargc, pyargv); 
     844 
     845 
     846        uwsgi.py_apps = PyDict_New (); 
     847        if (!uwsgi.py_apps) { 
     848                PyErr_Print (); 
     849                exit (1); 
     850        } 
     851 
     852 
     853        wsgi_spitout = PyCFunction_New (uwsgi_spit_method, NULL); 
     854        wsgi_writeout = PyCFunction_New (uwsgi_write_method, NULL); 
     855 
     856#ifndef PYTHREE 
     857#ifndef ROCK_SOLID 
     858        uwsgi_module = Py_InitModule ("uwsgi", null_methods); 
     859        if (uwsgi_module == NULL) { 
     860                fprintf (stderr, "could not initialize the uwsgi python module\n"); 
     861                exit (1); 
     862        } 
     863        if (uwsgi.sharedareasize > 0) { 
     864#ifndef __OpenBSD__ 
     865                uwsgi.sharedareamutex = mmap (NULL, sizeof (pthread_mutexattr_t) + sizeof (pthread_mutex_t), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0); 
     866                if (!uwsgi.sharedareamutex) { 
     867                        perror ("mmap()"); 
     868                        exit (1); 
     869                } 
     870#else 
     871                fprintf (stderr, "***WARNING*** the sharedarea on OpenBSD is not SMP-safe. Beware of race conditions !!!\n"); 
     872#endif 
     873                uwsgi.sharedarea = mmap (NULL, uwsgi.page_size * uwsgi.sharedareasize, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0); 
     874                if (uwsgi.sharedarea) { 
     875                        fprintf (stderr, "shared area mapped at %p, you can access it with uwsgi.sharedarea* functions.\n", uwsgi.sharedarea); 
     876 
     877#ifdef __APPLE__ 
     878                        memset (uwsgi.sharedareamutex, 0, sizeof (OSSpinLock)); 
     879#else 
     880#ifndef __OpenBSD__ 
     881                        if (pthread_mutexattr_init ((pthread_mutexattr_t *) uwsgi.sharedareamutex)) { 
     882                                fprintf (stderr, "unable to allocate mutexattr structure\n"); 
     883                                exit (1); 
     884                        } 
     885                        if (pthread_mutexattr_setpshared ((pthread_mutexattr_t *) uwsgi.sharedareamutex, PTHREAD_PROCESS_SHARED)) { 
     886                                fprintf (stderr, "unable to share mutex\n"); 
     887                                exit (1); 
     888                        } 
     889                        if (pthread_mutex_init ((pthread_mutex_t *) uwsgi.sharedareamutex + sizeof (pthread_mutexattr_t), (pthread_mutexattr_t *) uwsgi.sharedareamutex)) { 
     890                                fprintf (stderr, "unable to initialize mutex\n"); 
     891                                exit (1); 
     892                        } 
     893#endif 
     894#endif 
     895 
     896                } 
     897                else { 
     898                        perror ("mmap()"); 
     899                        exit (1); 
     900                } 
     901 
     902        } 
     903 
     904        init_uwsgi_embedded_module (); 
     905#endif 
     906#endif 
     907 
     908 
     909 
     910#ifdef UWSGI_ONEAPP 
     911 
     912 
     913        wi = malloc (sizeof (struct uwsgi_app)); 
     914        if (wi == NULL) { 
     915                perror ("malloc()"); 
     916                exit (1); 
     917        } 
     918        memset (wi, 0, sizeof (struct uwsgi_app)); 
     919 
     920        // load wsgi module/script 
     921        for (i = optind; i < argc; i++) { 
     922                init_uwsgi_vars (); 
     923                wi->wsgi_module = PyImport_ImportModule (argv[i]); 
     924                if (!wi->wsgi_module) { 
     925                        PyErr_Print (); 
     926                        exit (1); 
     927                } 
     928                wi->wsgi_dict = PyModule_GetDict (wi->wsgi_module); 
     929                if (!wi->wsgi_dict) { 
     930                        PyErr_Print (); 
     931                        exit (1); 
     932                } 
     933                wi->wsgi_callable = PyDict_GetItemString (wi->wsgi_dict, "application"); 
     934                if (!wi->wsgi_callable) { 
     935                        PyErr_Print (); 
     936                        exit (1); 
     937                } 
     938                wi->wsgi_environ = PyDict_New (); 
     939                if (!wi->wsgi_environ) { 
     940                        PyErr_Print (); 
     941                        exit (1); 
     942                } 
     943 
     944                wi->wsgi_harakiri = PyDict_GetItemString (wi->wsgi_dict, "harakiri"); 
     945 
     946                wi->wsgi_args = PyTuple_New (2); 
     947                if (!wi->wsgi_args) { 
     948                        PyErr_Print (); 
     949                        exit (1); 
     950                } 
     951                if (PyTuple_SetItem (wi->wsgi_args, 0, wi->wsgi_environ)) { 
     952                        PyErr_Print (); 
     953                        exit (1); 
     954                } 
     955                if (PyTuple_SetItem (wi->wsgi_args, 1, wsgi_spitout)) { 
     956                        PyErr_Print (); 
     957                        exit (1); 
     958                } 
     959                break; 
     960        } 
     961 
     962        if (!wi->wsgi_module) { 
     963                fprintf (stderr, "unable to find the wsgi script. Have you specified it ?\n"); 
     964                exit (1); 
     965        } 
     966#endif 
     967 
     968        Py_OptimizeFlag = uwsgi.py_optimize; 
     969 
     970        uwsgi.main_thread = PyThreadState_Get (); 
     971 
     972 
     973#ifdef UWSGI_THREADING 
     974        if (uwsgi.has_threads) { 
     975                PyEval_InitThreads (); 
     976                fprintf (stderr, "threads support enabled\n"); 
     977        } 
     978 
     979#endif 
     980 
     981        if (!no_server) { 
     982#ifndef UNBIT 
     983                if (uwsgi.socket_name != NULL && !uwsgi.is_a_reload) { 
     984#ifdef UWSGI_SCTP 
     985                        if (!strncmp (uwsgi.socket_name, "sctp:", 5)) { 
     986                                char *sctp_port = strchr (uwsgi.socket_name + 5, ':'); 
     987                                if (sctp_port == NULL) { 
     988                                        fprintf (stderr, "invalid SCTP port ! syntax: sctp:ip1,ip2,ipN:port\n"); 
     989                                        exit (1); 
     990                                } 
     991                                uwsgi.serverfd = bind_to_sctp (uwsgi.socket_name + 5, uwsgi.listen_queue, sctp_port); 
     992                                i_am_sctp = 1; 
     993                        } 
     994                        else { 
     995#endif 
     996                                char *tcp_port = strchr (uwsgi.socket_name, ':'); 
     997                                if (tcp_port == NULL) { 
     998                                        uwsgi.serverfd = bind_to_unix (uwsgi.socket_name, uwsgi.listen_queue, uwsgi.chmod_socket, uwsgi.abstract_socket); 
     999                                } 
     1000                                else { 
     1001                                        uwsgi.serverfd = bind_to_tcp (uwsgi.socket_name, uwsgi.listen_queue, tcp_port); 
     1002                                } 
     1003 
     1004                                if (uwsgi.serverfd < 0) { 
     1005                                        fprintf (stderr, "unable to create the server socket.\n"); 
     1006                                        exit (1); 
     1007                                } 
     1008#ifdef UWSGI_SCTP 
     1009                        } 
     1010#endif 
     1011                } 
     1012#endif 
     1013 
     1014                socket_type_len = sizeof (int); 
     1015                if (getsockopt (uwsgi.serverfd, SOL_SOCKET, SO_TYPE, &socket_type, &socket_type_len)) { 
     1016                        perror ("getsockopt()"); 
     1017                        fprintf(stderr, "The -s/--socket option is missing and stdin is not a socket.\n"); 
     1018                        exit (1); 
     1019                } 
     1020 
     1021        } 
     1022 
     1023 
     1024 
     1025        if (uwsgi.single_interpreter == 1) { 
     1026                init_uwsgi_vars (); 
     1027        } 
     1028 
     1029        memset (uwsgi.wsgi_apps, 0, sizeof (uwsgi.wsgi_apps)); 
     1030 
     1031 
     1032 
     1033        uwsgi.poll.events = POLLIN; 
     1034 
     1035        memset (&wsgi_req, 0, sizeof (struct wsgi_request)); 
     1036 
     1037        /* shared area for workers */ 
     1038        uwsgi.workers = (struct uwsgi_worker *) mmap (NULL, sizeof (struct uwsgi_worker) * uwsgi.numproc + 1, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0); 
     1039        if (!uwsgi.workers) { 
     1040                perror ("mmap()"); 
     1041                exit (1); 
     1042        } 
     1043        memset (uwsgi.workers, 0, sizeof (struct uwsgi_worker) * uwsgi.numproc + 1); 
     1044 
     1045        uwsgi.mypid = getpid (); 
     1046        masterpid = uwsgi.mypid; 
     1047 
     1048#ifndef UNBIT 
     1049        if (uwsgi.pidfile) { 
     1050                fprintf (stderr, "writing pidfile to %s\n", uwsgi.pidfile); 
     1051                pidfile = fopen (uwsgi.pidfile, "w"); 
     1052                if (!pidfile) { 
     1053                        perror ("fopen"); 
     1054                        exit (1); 
     1055                } 
     1056                if (fprintf (pidfile, "%d\n", masterpid) < 0) { 
     1057                        fprintf (stderr, "could not write pidfile.\n"); 
     1058                } 
     1059                fclose (pidfile); 
     1060        } 
     1061#endif 
     1062 
     1063        if (uwsgi.buffer_size > 65536) { 
     1064                fprintf (stderr, "invalid buffer size.\n"); 
     1065                exit (1); 
     1066        } 
     1067        buffer = malloc (uwsgi.buffer_size); 
     1068        if (buffer == NULL) { 
     1069                fprintf (stderr, "unable to allocate memory for buffer.\n"); 
     1070                exit (1); 
     1071        } 
     1072 
     1073        fprintf (stderr, "request/response buffer (%d bytes) allocated.\n", uwsgi.buffer_size); 
     1074 
     1075        /* save the masterpid */ 
     1076        uwsgi.workers[0].pid = masterpid; 
     1077 
     1078        fprintf(stderr,"initializing hooks..."); 
     1079 
     1080        uwsgi.hooks[0] = uwsgi_request_wsgi ;  
     1081        uwsgi.after_hooks[0] = uwsgi_after_request_wsgi ;  
     1082 
     1083        uwsgi.hooks[UWSGI_MODIFIER_ADMIN_REQUEST] = uwsgi_request_admin ; //10 
     1084#ifdef UWSGI_SPOOLER 
     1085        uwsgi.hooks[UWSGI_MODIFIER_SPOOL_REQUEST] = uwsgi_request_spooler ; //17 
     1086#endif 
     1087        uwsgi.hooks[UWSGI_MODIFIER_FASTFUNC] = uwsgi_request_fastfunc ; //26 
     1088 
     1089        uwsgi.hooks[UWSGI_MODIFIER_MANAGE_PATH_INFO] = uwsgi_request_wsgi ; // 30 
     1090        uwsgi.after_hooks[UWSGI_MODIFIER_MANAGE_PATH_INFO] = uwsgi_after_request_wsgi; // 30 
     1091 
     1092        uwsgi.hooks[UWSGI_MODIFIER_MESSAGE_MARSHAL] = uwsgi_request_marshal ; //33 
     1093        uwsgi.hooks[UWSGI_MODIFIER_PING] = uwsgi_request_ping ; //100 
     1094 
     1095        fprintf(stderr,"done.\n"); 
     1096 
     1097#ifdef UWSGI_ERLANG 
     1098        if (uwsgi.erlang_node) { 
     1099                uwsgi.erlangfd = init_erlang(uwsgi.erlang_node); 
     1100        } 
     1101#endif 
     1102 
     1103 
     1104 
     1105        if (uwsgi.wsgi_config != NULL) { 
     1106                uwsgi_wsgi_config (); 
     1107        } 
     1108#ifdef UWSGI_XML 
     1109        else if (uwsgi.xml_config != NULL) { 
     1110                uwsgi_xml_config (&wsgi_req, NULL); 
     1111        } 
     1112#endif 
     1113 
     1114#ifdef UWSGI_PASTE 
     1115        else if (uwsgi.paste != NULL) { 
     1116                uwsgi_paste_config (); 
     1117        } 
     1118#endif 
     1119 
     1120        if (uwsgi.test_module != NULL) { 
     1121                if (PyImport_ImportModule (uwsgi.test_module)) { 
     1122                        exit (0); 
     1123                } 
     1124                exit (1); 
     1125        } 
     1126 
     1127 
     1128 
     1129#ifndef UNBIT 
     1130#ifndef ROCK_SOLID 
     1131        if (no_server) { 
     1132                fprintf (stderr, "no-server mode requested. Goodbye.\n"); 
     1133                exit (0); 
     1134        } 
     1135#endif 
     1136#endif 
     1137 
     1138        if (!uwsgi.single_interpreter) { 
     1139                fprintf(stderr,"*** uWSGI is running in multiple interpreter mode !!! ***\n"); 
     1140        } 
     1141 
     1142        /* preforking() */ 
     1143        if (uwsgi.master_process) { 
     1144                if (uwsgi.is_a_reload) { 
     1145                        fprintf (stderr, "gracefully (RE)spawned uWSGI master process (pid: %d)\n", uwsgi.mypid); 
     1146                } 
     1147                else { 
     1148                        fprintf (stderr, "spawned uWSGI master process (pid: %d)\n", uwsgi.mypid); 
     1149                } 
     1150        } 
     1151 
     1152#ifdef UNBIT 
     1153        if (single_app_mode == 1) { 
     1154                wsgi_req.wsgi_script = getenv ("UWSGI_SCRIPT"); 
     1155                if (wsgi_req.wsgi_script) { 
     1156                        wsgi_req.wsgi_script_len = strlen (wsgi_req.wsgi_script); 
     1157                } 
     1158                else { 
     1159                        fprintf (stderr, "UWSGI_SCRIPT env var not set !\n"); 
     1160                        exit (1); 
     1161                } 
     1162 
     1163                init_uwsgi_app (NULL, NULL); 
     1164        } 
     1165#endif 
     1166 
     1167#ifdef UWSGI_SPOOLER 
     1168        if (spool_dir != NULL) { 
     1169                uwsgi.workers[0].spooler_pid = spooler_start (uwsgi.serverfd, uwsgi_module); 
     1170        } 
     1171#endif 
     1172 
     1173 
     1174        if (!uwsgi.master_process) { 
     1175                if (uwsgi.numproc == 1) { 
     1176                        fprintf (stderr, "spawned uWSGI worker 1 (and the only) (pid: %d)\n", masterpid); 
     1177                } 
     1178                else { 
     1179                        fprintf (stderr, "spawned uWSGI worker 1 (pid: %d)\n", masterpid); 
     1180                } 
     1181                uwsgi.workers[1].pid = masterpid; 
     1182                uwsgi.workers[1].id = 1; 
     1183                uwsgi.workers[1].last_spawn = time (NULL); 
     1184                uwsgi.workers[1].manage_next_request = 1; 
     1185#ifdef UWSGI_THREADING 
     1186                uwsgi.workers[1].i_have_gil = 1; 
     1187#endif 
     1188                uwsgi.mywid = 1; 
     1189                gettimeofday (&last_respawn, NULL); 
     1190                respawn_delta = last_respawn.tv_sec; 
     1191        } 
     1192 
     1193 
     1194                for (i = 2-uwsgi.master_process ; i < uwsgi.numproc + 1; i++) { 
     1195                        /* let the worker know his worker_id (wid) */ 
     1196                        pid = fork (); 
     1197                        if (pid == 0) { 
     1198                                uwsgi.mypid = getpid (); 
     1199                                uwsgi.workers[i].pid = uwsgi.mypid; 
     1200                                uwsgi.workers[i].id = i; 
     1201                                uwsgi.workers[i].last_spawn = time (NULL); 
     1202                                uwsgi.workers[i].manage_next_request = 1; 
     1203#ifdef UWSGI_THREADING 
     1204                                uwsgi.workers[i].i_have_gil = 1; 
     1205#endif 
     1206                                uwsgi.mywid = i; 
     1207                                if (uwsgi.serverfd != 0 && uwsgi.master_process == 1) { 
     1208                                        /* close STDIN for workers */ 
     1209                                        close (0); 
     1210                                } 
     1211                                break; 
     1212                        } 
     1213                        else if (pid < 1) { 
     1214                                perror ("fork()"); 
     1215                                exit (1); 
     1216                        } 
     1217                        else { 
     1218                                fprintf (stderr, "spawned uWSGI worker %d (pid: %d)\n", i, pid); 
     1219                                gettimeofday (&last_respawn, NULL); 
     1220                                respawn_delta = last_respawn.tv_sec; 
     1221                        } 
     1222                } 
     1223 
     1224 
     1225        if (getpid () == masterpid && uwsgi.master_process == 1) { 
     1226                /* route signals to workers... */ 
     1227                signal (SIGHUP, (void *) &grace_them_all); 
     1228                signal (SIGTERM, (void *) &reap_them_all); 
     1229                signal (SIGINT, (void *) &kill_them_all); 
     1230                signal (SIGQUIT, (void *) &kill_them_all); 
     1231                /* used only to avoid human-errors */ 
     1232#ifndef UNBIT 
     1233                signal (SIGUSR1, (void *) &stats); 
     1234#endif 
     1235 
     1236                if (udp_socket) { 
     1237                        udp_poll.fd = bind_to_udp (udp_socket); 
     1238                        if (udp_poll.fd < 0) { 
     1239                                fprintf (stderr, "unable to bind to udp socket. SNMP and cluster management services will be disabled.\n"); 
     1240                        } 
     1241                        else { 
     1242                                fprintf (stderr, "UDP server enabled.\n"); 
     1243                                udp_poll.events = POLLIN; 
     1244                        } 
     1245                } 
     1246                for (;;) { 
     1247                        if (ready_to_die >= uwsgi.numproc && uwsgi.to_hell) { 
     1248#ifdef UWSGI_SPOOLER 
     1249                                if (spool_dir && uwsgi.workers[0].spooler_pid > 0) { 
     1250                                        kill (uwsgi.workers[0].spooler_pid, SIGKILL); 
     1251                                        fprintf(stderr,"killed the spooler with pid %d\n", uwsgi.workers[0].spooler_pid); 
     1252                                } 
     1253 
     1254#endif 
     1255                                fprintf (stderr, "goodbye to uWSGI.\n"); 
     1256                                exit (0); 
     1257                        } 
     1258                        if (ready_to_reload >= uwsgi.numproc && uwsgi.to_heaven) { 
     1259#ifdef UWSGI_SPOOLER 
     1260                                if (spool_dir && uwsgi.workers[0].spooler_pid > 0) { 
     1261                                        kill (uwsgi.workers[0].spooler_pid, SIGKILL); 
     1262                                        fprintf(stderr,"wait4() the spooler with pid %d...", uwsgi.workers[0].spooler_pid); 
     1263                                        diedpid = waitpid(uwsgi.workers[0].spooler_pid, &waitpid_status, 0); 
     1264                                        fprintf(stderr,"done."); 
     1265                                } 
     1266#endif 
     1267                                fprintf (stderr, "binary reloading uWSGI...\n"); 
     1268                                if (chdir (cwd)) { 
     1269                                        perror ("chdir()"); 
     1270                                        exit (1); 
     1271                                } 
     1272                                /* check fd table (a module can obviosly open some fd on initialization...) */ 
     1273                                fprintf (stderr, "closing all fds > 2 (_SC_OPEN_MAX = %ld)...\n", sysconf (_SC_OPEN_MAX)); 
     1274                                for (i = 3; i < sysconf (_SC_OPEN_MAX); i++) { 
     1275                                        if (i == uwsgi.serverfd) { 
     1276                                                continue; 
     1277                                        } 
     1278                                        close (i); 
     1279                                } 
     1280                                if (uwsgi.serverfd != 3) { 
     1281                                        if (dup2 (uwsgi.serverfd, 3) < 0) { 
     1282                                                perror ("dup2()"); 
     1283                                                exit (1); 
     1284                                        } 
     1285                                } 
     1286                                fprintf (stderr, "running %s\n", uwsgi.binary_path); 
     1287                                strcpy (argv[0], uwsgi.binary_path); 
     1288                                execve (uwsgi.binary_path, argv, environ); 
     1289                                perror ("execve()"); 
     1290                                // never here 
     1291                                exit (1); 
     1292                        } 
     1293                        diedpid = waitpid (WAIT_ANY, &waitpid_status, WNOHANG); 
     1294                        if (diedpid == -1) { 
     1295                                perror ("waitpid()"); 
     1296                                /* here is better to reload all the uWSGI stack */ 
     1297                                fprintf (stderr, "something horrible happened...\n"); 
     1298                                reap_them_all (); 
     1299                                exit (1); 
     1300                        } 
     1301                        else if (diedpid == 0) { 
     1302                                /* PLEASE, do not run python threads in the master process, you can potentially destroy the world, 
     1303                                   we support this for hyperultramegagodprogrammer and systems 
     1304                                 */ 
     1305#ifdef UWSGI_THREADING 
     1306                                if (uwsgi.has_threads && uwsgi.options[UWSGI_OPTION_THREADS] == 1) { 
     1307                                        uwsgi._save = PyEval_SaveThread (); 
     1308                                        uwsgi.workers[uwsgi.mywid].i_have_gil = 0; 
     1309                                } 
     1310#endif 
     1311                                /* all processes ok, doing status scan after N seconds */ 
     1312                                check_interval.tv_sec = uwsgi.options[UWSGI_OPTION_MASTER_INTERVAL]; 
     1313                                if (!check_interval.tv_sec) 
     1314                                        check_interval.tv_sec = 1; 
     1315                                 
     1316                                if (udp_socket && udp_poll.fd >= 0) { 
     1317                                        rlen = poll (&udp_poll, 1, check_interval.tv_sec * 1000); 
     1318                                        if (rlen < 0) { 
     1319                                                perror ("poll()"); 
     1320                                        } 
     1321                                        else if (rlen > 0) { 
     1322                                                udp_len = sizeof (udp_client); 
     1323                                                rlen = recvfrom (udp_poll.fd, buffer, uwsgi.buffer_size, 0, (struct sockaddr *) &udp_client, &udp_len); 
     1324                                                if (rlen < 0) { 
     1325                                                        perror ("recvfrom()"); 
     1326                                                } 
     1327                                                else if (rlen > 0) { 
     1328                                                        memset (udp_client_addr, 0, 16); 
     1329                                                        if (inet_ntop (AF_INET, &udp_client.sin_addr.s_addr, udp_client_addr, 16)) { 
     1330                                                                fprintf (stderr, "received udp packet of %d bytes from %s:%d\n", rlen, udp_client_addr, ntohs (udp_client.sin_port)); 
     1331                                                                if (buffer[0] == 0x30) { 
     1332                                                                        manage_snmp (udp_poll.fd, (uint8_t *) buffer, rlen, &udp_client); 
     1333                                                                } 
     1334                                                        } 
     1335                                                        else { 
     1336                                                                perror ("inet_ntop()"); 
     1337                                                        } 
     1338                                                } 
     1339                                        } 
     1340                                } 
     1341                                else { 
     1342                                        select (0, NULL, NULL, NULL, &check_interval); 
     1343                                } 
     1344                                working_workers = 0; 
     1345                                blocking_workers = 0; 
     1346#ifdef UWSGI_THREADING 
     1347                                if (uwsgi.has_threads && !uwsgi.workers[uwsgi.mywid].i_have_gil) { 
     1348                                        PyEval_RestoreThread (uwsgi._save); 
     1349                                        uwsgi.workers[uwsgi.mywid].i_have_gil = 1; 
     1350                                } 
     1351#endif 
     1352                                check_interval.tv_sec = uwsgi.options[UWSGI_OPTION_MASTER_INTERVAL]; 
     1353                                if (!check_interval.tv_sec) 
     1354                                        check_interval.tv_sec = 1; 
     1355                                for (i = 1; i <= uwsgi.numproc; i++) { 
     1356                                        /* first check for harakiri */ 
     1357                                        if (uwsgi.workers[i].harakiri > 0) { 
     1358                                                if (uwsgi.workers[i].harakiri < time (NULL)) { 
     1359                                                        /* first try to invoke the harakiri() custom handler */ 
     1360                                                        /* TODO */ 
     1361                                                        /* then brutally kill the worker */ 
     1362                                                        kill (uwsgi.workers[i].pid, SIGKILL); 
     1363                                                } 
     1364                                        } 
     1365                                        /* load counters */ 
     1366                                        if (uwsgi.workers[i].status & UWSGI_STATUS_IN_REQUEST) 
     1367                                                working_workers++; 
     1368 
     1369                                        if (uwsgi.workers[i].status & UWSGI_STATUS_BLOCKING) 
     1370                                                blocking_workers++; 
     1371 
     1372                                        uwsgi.workers[i].last_running_time = uwsgi.workers[i].running_time; 
     1373                                } 
     1374 
     1375                                continue; 
     1376 
     1377                        } 
     1378#ifdef UWSGI_SPOOLER 
     1379                        /* reload the spooler */ 
     1380                        if (spool_dir && uwsgi.workers[0].spooler_pid > 0) { 
     1381                                if (diedpid == uwsgi.workers[0].spooler_pid) { 
     1382                                        fprintf(stderr,"OOOPS the spooler is no more...trying respawn...\n"); 
     1383                                        uwsgi.workers[0].spooler_pid = spooler_start (uwsgi.serverfd, uwsgi_module); 
     1384                                        continue; 
     1385                                } 
     1386                        } 
     1387#endif 
     1388                        /* check for reloading */ 
     1389                        if (WIFEXITED (waitpid_status)) { 
     1390                                if (WEXITSTATUS (waitpid_status) == UWSGI_RELOAD_CODE && uwsgi.to_heaven) { 
     1391                                        ready_to_reload++; 
     1392                                        continue; 
     1393                                } 
     1394                                else if (WEXITSTATUS (waitpid_status) == UWSGI_END_CODE && uwsgi.to_hell) { 
     1395                                        ready_to_die++; 
     1396                                        continue; 
     1397                                } 
     1398                        } 
     1399 
     1400                        fprintf (stderr, "DAMN ! process %d died :( trying respawn ...\n", diedpid); 
     1401                        gettimeofday (&last_respawn, NULL); 
     1402                        if (last_respawn.tv_sec == respawn_delta) { 
     1403                                fprintf (stderr, "worker respawning too fast !!! i have to sleep a bit...\n"); 
     1404                                /* TODO, user configurable fork throttler */ 
     1405                                sleep (2); 
     1406                        } 
     1407                        gettimeofday (&last_respawn, NULL); 
     1408                        respawn_delta = last_respawn.tv_sec; 
     1409                        uwsgi.mywid = find_worker_id (diedpid); 
     1410                        pid = fork (); 
     1411                        if (pid == 0) { 
     1412                                uwsgi.mypid = getpid (); 
     1413                                uwsgi.workers[uwsgi.mywid].pid = uwsgi.mypid; 
     1414                                uwsgi.workers[uwsgi.mywid].harakiri = 0; 
     1415                                uwsgi.workers[uwsgi.mywid].requests = 0; 
     1416                                uwsgi.workers[uwsgi.mywid].failed_requests = 0; 
     1417                                uwsgi.workers[uwsgi.mywid].respawn_count++; 
     1418                                uwsgi.workers[uwsgi.mywid].last_spawn = time (NULL); 
     1419                                uwsgi.workers[uwsgi.mywid].manage_next_request = 1; 
     1420                                uwsgi.workers[uwsgi.mywid].i_have_gil = 1; 
     1421                                break; 
     1422                        } 
     1423                        else if (pid < 1) { 
     1424                                perror ("fork()"); 
     1425                        } 
     1426                        else { 
     1427                                fprintf (stderr, "Respawned uWSGI worker (new pid: %d)\n", pid); 
     1428#ifdef UWSGI_SPOOLER 
     1429                                if (uwsgi.mywid <= 0 && diedpid != uwsgi.workers[0].spooler_pid) { 
     1430#else 
     1431                                if (uwsgi.mywid <= 0) { 
     1432#endif 
     1433                                        fprintf (stderr, "warning the died pid was not in the workers list. Probably you hit a BUG of uWSGI\n"); 
     1434                                } 
     1435                        } 
     1436                } 
     1437        } 
     1438 
     1439 
     1440 
     1441 
     1442        uwsgi.hvec = malloc (sizeof (struct iovec) * uwsgi.vec_size); 
     1443        if (uwsgi.hvec == NULL) { 
     1444                fprintf (stderr, "unable to allocate memory for iovec.\n"); 
     1445                exit (1); 
     1446        } 
     1447 
     1448        if (uwsgi.options[UWSGI_OPTION_HARAKIRI] > 0 && !uwsgi.master_process) { 
     1449                signal (SIGALRM, (void *) &harakiri); 
     1450        } 
     1451 
     1452        /* gracefully reload */ 
     1453        signal (SIGHUP, (void *) &gracefully_kill); 
     1454        /* close the process (useful for master INT) */ 
     1455        signal (SIGINT, (void *) &end_me); 
     1456        /* brutally reload */ 
     1457        signal (SIGTERM, (void *) &reload_me); 
     1458 
     1459 
     1460#ifndef UNBIT 
     1461        signal (SIGUSR1, (void *) &stats); 
     1462#endif 
     1463 
     1464 
     1465        signal (SIGPIPE, (void *) &warn_pipe); 
     1466 
     1467 
     1468#ifdef UWSGI_ERLANG 
     1469        if (uwsgi.erlang_nodes > 0) { 
     1470                if ( (uwsgi.mywid - uwsgi.erlang_nodes) <= (uwsgi.numproc - uwsgi.erlang_nodes)) { 
     1471                        erlang_loop(buffer); 
     1472                        // NEVER HERE 
     1473                        exit(1); 
     1474                } 
     1475        } 
     1476        else { 
     1477                // close the erlang server fd for python workers 
     1478                close(uwsgi.erlangfd); 
     1479        } 
     1480#endif 
     1481 
     1482#ifdef UWSGI_THREADING 
     1483        // release the GIL 
     1484        if (uwsgi.has_threads) { 
     1485                uwsgi._save = PyEval_SaveThread (); 
     1486                uwsgi.workers[uwsgi.mywid].i_have_gil = 0; 
     1487        } 
     1488#endif 
     1489 
     1490 
     1491        while (uwsgi.workers[uwsgi.mywid].manage_next_request) { 
     1492 
     1493 
     1494                wsgi_req.app_id = uwsgi.default_app; 
     1495#ifdef UWSGI_SENDFILE 
     1496                wsgi_req.sendfile_fd = -1; 
     1497#endif 
     1498                // clear all status bits 
     1499                UWSGI_CLEAR_STATUS ; 
     1500 
     1501                uwsgi.poll.fd = accept (uwsgi.serverfd, (struct sockaddr *) &c_addr, (socklen_t *) & c_len); 
     1502 
     1503                if (uwsgi.poll.fd < 0) { 
     1504                        perror ("accept()"); 
     1505                        continue; 
     1506                } 
     1507 
     1508                UWSGI_SET_IN_REQUEST; 
     1509 
     1510                if (uwsgi.options[UWSGI_OPTION_LOGGING]) 
     1511                        gettimeofday (&wsgi_req.start_of_request, NULL); 
     1512 
     1513                 
     1514 
     1515#ifdef UWSGI_SCTP 
     1516                if (i_am_sctp == 1) { 
     1517                        // get stream id, and map it to uwsgi modifiers 
     1518                        struct sctp_status sstatus; 
     1519                        memset (&sstatus, 0, sizeof (sstatus)); 
     1520                        socklen_t slen = sizeof (sstatus); 
     1521                        sstatus.sstat_assoc_id = 1; 
     1522                        if (getsockopt (uwsgi.poll.fd, IPPROTO_SCTP, SCTP_STATUS, &sstatus, &slen)) { 
     1523                                perror ("getsockopt()"); 
     1524                        } 
     1525 
     1526                        memset (&sctp_ss, 0, sizeof (sctp_ss)); 
     1527 
     1528                        fprintf (stderr, "%d %d\n", sstatus.sstat_instrms, sstatus.sstat_outstrms); 
     1529 
     1530                        i = 0; 
     1531                        wsgi_req.size = sctp_recvmsg (uwsgi.poll.fd, buffer, uwsgi.buffer_size, 0, 0, &sctp_ss, 0); 
     1532                        if (wsgi_req.size < 0) { 
     1533                                perror ("sctp_recvmsg()"); 
     1534                        } 
     1535                        fprintf (stderr, "received uwsgi message of %d bytes on stream id %d flags %d\n", wsgi_req.size, ntohs (sctp_ss.sinfo_stream), i); 
     1536 
     1537                } 
     1538                else { 
     1539#endif 
     1540                        if (!uwsgi_parse_response (&uwsgi.poll, uwsgi.options[UWSGI_OPTION_SOCKET_TIMEOUT], (struct uwsgi_header *) &wsgi_req, buffer)) { 
     1541                                continue; 
     1542                        } 
     1543#ifdef UWSGI_SCTP 
     1544                } 
     1545#endif 
     1546 
     1547                // enter harakiri mode 
     1548                if (uwsgi.options[UWSGI_OPTION_HARAKIRI] > 0) { 
     1549                        set_harakiri(uwsgi.options[UWSGI_OPTION_HARAKIRI]); 
     1550                } 
     1551 
     1552                ret = (*uwsgi.hooks[wsgi_req.modifier])(&uwsgi, &wsgi_req, buffer); 
     1553                // calculate execution time 
     1554                gettimeofday(&wsgi_req.end_of_request, NULL) ; 
     1555                uwsgi.workers[uwsgi.mywid].running_time += (double) (( (double)(wsgi_req.end_of_request.tv_sec*1000000+wsgi_req.end_of_request.tv_usec)-(double)(wsgi_req.start_of_request.tv_sec*1000000+wsgi_req.start_of_request.tv_usec))/ (double)1000.0) ; 
     1556 
     1557 
     1558                // get memory usage 
     1559                if (uwsgi.options[UWSGI_OPTION_MEMORY_DEBUG] == 1) 
     1560                        get_memusage(); 
     1561 
     1562                // close the connection with the webserver 
     1563                close(uwsgi.poll.fd); 
     1564                uwsgi.workers[0].requests++; 
     1565                uwsgi.workers[uwsgi.mywid].requests++; 
     1566 
     1567                if (!ret) 
     1568                        (*uwsgi.after_hooks[wsgi_req.modifier])(&uwsgi, &wsgi_req, buffer); 
     1569 
     1570 
     1571                // leave harakiri mode 
     1572                if (uwsgi.workers[uwsgi.mywid].harakiri > 0) { 
     1573                        set_harakiri(0); 
     1574                } 
     1575 
     1576 
     1577                // defunct process reaper 
     1578                if (uwsgi.options[UWSGI_OPTION_REAPER] == 1) { 
     1579                        waitpid (-1, &waitpid_status, WNOHANG); 
     1580                } 
     1581                // reset request 
     1582                memset (&wsgi_req, 0, sizeof (struct wsgi_request)); 
     1583#ifdef UNBIT 
     1584                if (tmp_filename && tmp_dir_fd >= 0) { 
     1585                        tmp_filename[0] = 0; 
     1586                } 
     1587#endif 
     1588 
     1589                if (uwsgi.options[UWSGI_OPTION_MAX_REQUESTS] > 0 && uwsgi.workers[uwsgi.mywid].requests >= uwsgi.options[UWSGI_OPTION_MAX_REQUESTS]) { 
     1590                        goodbye_cruel_world (); 
     1591                } 
     1592 
     1593#ifdef UNBIT 
     1594                if (check_for_memory_errors) { 
     1595                        if (syscall (357, &us, 0) > 0) { 
     1596                                if (us.memory_errors > 0) { 
     1597                                        fprintf (stderr, "Unbit Kernel found a memory allocation error for process %d.\n", uwsgi.mypid); 
     1598                                        goodbye_cruel_world (); 
     1599                                } 
     1600                        } 
     1601                } 
     1602#endif 
     1603 
     1604        } 
     1605 
     1606        if (uwsgi.workers[uwsgi.mywid].manage_next_request == 0) { 
     1607                reload_me (); 
     1608        } 
     1609        else { 
     1610                goodbye_cruel_world (); 
     1611        } 
     1612 
     1613        /* never here */ 
     1614        return 0; 
     1615} 
     1616 
     1617void init_uwsgi_vars () { 
     1618 
     1619#ifndef UNBIT 
     1620        int i; 
     1621#endif 
     1622        PyObject *pysys, *pysys_dict, *pypath; 
     1623 
     1624        /* add cwd to pythonpath */ 
     1625        pysys = PyImport_ImportModule ("sys"); 
     1626        if (!pysys) { 
     1627                PyErr_Print (); 
     1628                exit (1); 
     1629        } 
     1630        pysys_dict = PyModule_GetDict (pysys); 
     1631        pypath = PyDict_GetItemString (pysys_dict, "path"); 
     1632        if (!pypath) { 
     1633                PyErr_Print (); 
     1634                exit (1); 
     1635        } 
     1636        if (PyList_Insert (pypath, 0, PyString_FromString (".")) != 0) { 
     1637                PyErr_Print (); 
     1638        } 
     1639 
     1640#ifndef UNBIT 
     1641        for (i = 0; i < uwsgi.python_path_cnt; i++) { 
     1642                if (PyList_Insert (pypath, 0, PyString_FromString (uwsgi.python_path[i])) != 0) { 
     1643                        PyErr_Print (); 
     1644                } 
     1645                else { 
     1646                        fprintf (stderr, "added %s to pythonpath.\n", uwsgi.python_path[i]); 
     1647                } 
     1648        } 
     1649#endif 
     1650 
     1651} 
     1652 
     1653#ifndef ROCK_SOLID 
     1654int init_uwsgi_app (PyObject * force_wsgi_dict, PyObject * my_callable) { 
     1655        PyObject *wsgi_module, *wsgi_dict = NULL; 
     1656        PyObject *pymain, *zero; 
     1657        PyObject *pycprof, *pycprof_dict; 
     1658        char tmpstring[256]; 
     1659        int id; 
     1660 
     1661        struct uwsgi_app *wi; 
     1662 
     1663        memset (tmpstring, 0, 256); 
     1664 
     1665 
     1666        if (wsgi_req.wsgi_script_len == 0 && ((wsgi_req.wsgi_module_len == 0 || wsgi_req.wsgi_callable_len == 0) && uwsgi.wsgi_config == NULL && my_callable == NULL)) { 
     1667                fprintf (stderr, "invalid application (%.*s). skip.\n", wsgi_req.script_name_len, wsgi_req.script_name); 
     1668                return -1; 
     1669        } 
     1670 
     1671        if (uwsgi.wsgi_config && wsgi_req.wsgi_callable_len == 0 && my_callable == NULL) { 
     1672                fprintf (stderr, "invalid application (%.*s). skip.\n", wsgi_req.script_name_len, wsgi_req.script_name); 
     1673                return -1; 
     1674        } 
     1675 
     1676        if (wsgi_req.wsgi_script_len > 255 || wsgi_req.wsgi_module_len > 255 || wsgi_req.wsgi_callable_len > 255) { 
     1677                fprintf (stderr, "invalid application's string size. skip.\n"); 
     1678                return -1; 
     1679        } 
     1680 
     1681        id = uwsgi.wsgi_cnt; 
     1682 
     1683 
     1684        if (wsgi_req.script_name_len == 0) { 
     1685                wsgi_req.script_name_len = 1; 
     1686                wsgi_req.script_name = (char *) app_slash; 
     1687                id = 0; 
     1688        } 
     1689        else if (wsgi_req.script_name_len == 1) { 
     1690                if (wsgi_req.script_name[0] == '/') { 
     1691                        id = 0; 
     1692                } 
     1693        } 
     1694 
     1695 
     1696        zero = PyString_FromStringAndSize (wsgi_req.script_name, wsgi_req.script_name_len); 
     1697        if (!zero) { 
     1698                Py_FatalError ("cannot get mountpoint python object !\n"); 
     1699        } 
     1700 
     1701        if (PyDict_GetItem (uwsgi.py_apps, zero) != NULL) { 
     1702                Py_DECREF (zero); 
     1703                fprintf (stderr, "mountpoint %.*s already configured. skip.\n", wsgi_req.script_name_len, wsgi_req.script_name); 
     1704                return -1; 
     1705        } 
     1706 
     1707        Py_DECREF (zero); 
     1708 
     1709        wi = &uwsgi.wsgi_apps[id]; 
     1710 
     1711        memset (wi, 0, sizeof (struct uwsgi_app)); 
     1712 
     1713        if (uwsgi.single_interpreter == 0) { 
     1714                wi->interpreter = Py_NewInterpreter (); 
     1715                if (!wi->interpreter) { 
     1716                        fprintf (stderr, "unable to initialize the new interpreter\n"); 
     1717                        exit (1); 
     1718                } 
     1719                PyThreadState_Swap (wi->interpreter); 
     1720#ifndef PYTHREE 
     1721                init_uwsgi_embedded_module (); 
     1722#endif 
     1723                init_uwsgi_vars (); 
     1724                fprintf (stderr, "interpreter for app %d initialized.\n", id); 
     1725        } 
     1726 
     1727        if (uwsgi.paste) { 
     1728                wi->wsgi_callable = my_callable; 
     1729                Py_INCREF (my_callable); 
     1730        } 
     1731 
     1732        else { 
     1733 
     1734                if (uwsgi.wsgi_config == NULL) { 
     1735                        if (wsgi_req.wsgi_script_len > 0) { 
     1736                                memcpy (tmpstring, wsgi_req.wsgi_script, wsgi_req.wsgi_script_len); 
     1737                                wsgi_module = PyImport_ImportModule (tmpstring); 
     1738                                if (!wsgi_module) { 
     1739                                        PyErr_Print (); 
     1740                                        if (uwsgi.single_interpreter == 0) { 
     1741                                                Py_EndInterpreter (wi->interpreter); 
     1742                                                PyThreadState_Swap (uwsgi.main_thread); 
     1743                                        } 
     1744                                        return -1; 
     1745                                } 
     1746                                wsgi_req.wsgi_callable = "application"; 
     1747                                wsgi_req.wsgi_callable_len = 11; 
     1748                        } 
     1749                        else { 
     1750                                memcpy (tmpstring, wsgi_req.wsgi_module, wsgi_req.wsgi_module_len); 
     1751                                wsgi_module = PyImport_ImportModule (tmpstring); 
     1752                                if (!wsgi_module) { 
     1753                                        PyErr_Print (); 
     1754                                        if (uwsgi.single_interpreter == 0) { 
     1755                                                Py_EndInterpreter (wi->interpreter); 
     1756                                                PyThreadState_Swap (uwsgi.main_thread); 
     1757                                        } 
     1758                                        return -1; 
     1759                                } 
     1760                        } 
     1761 
     1762                        wsgi_dict = PyModule_GetDict (wsgi_module); 
     1763                        if (!wsgi_dict) { 
     1764                                PyErr_Print (); 
     1765                                if (uwsgi.single_interpreter == 0) { 
     1766                                        Py_EndInterpreter (wi->interpreter); 
     1767                                        PyThreadState_Swap (uwsgi.main_thread); 
     1768                                } 
     1769                                return -1; 
     1770                        } 
     1771 
     1772                } 
     1773                else { 
     1774                        wsgi_dict = force_wsgi_dict; 
     1775                } 
     1776 
     1777 
     1778                memset (tmpstring, 0, 256); 
     1779                memcpy (tmpstring, wsgi_req.wsgi_callable, wsgi_req.wsgi_callable_len); 
     1780                if (my_callable) { 
     1781                        wi->wsgi_callable = my_callable; 
     1782                        Py_INCREF (my_callable); 
     1783                } 
     1784                else if (wsgi_dict) { 
     1785                        wi->wsgi_callable = PyDict_GetItemString (wsgi_dict, tmpstring); 
     1786                } 
     1787                else { 
     1788                        return -1; 
     1789                } 
     1790 
     1791        } 
     1792 
     1793 
     1794        if (!wi->wsgi_callable) { 
     1795                PyErr_Print (); 
     1796                if (uwsgi.single_interpreter == 0) { 
     1797                        Py_EndInterpreter (wi->interpreter); 
     1798                        PyThreadState_Swap (uwsgi.main_thread); 
     1799                } 
     1800                return -1; 
     1801        } 
     1802 
     1803 
     1804        wi->wsgi_environ = PyDict_New (); 
     1805        if (!wi->wsgi_environ) { 
     1806                PyErr_Print (); 
     1807                if (uwsgi.single_interpreter == 0) { 
     1808                        Py_EndInterpreter (wi->interpreter); 
     1809                        PyThreadState_Swap (uwsgi.main_thread); 
     1810                } 
     1811                return -1; 
     1812        } 
     1813 
     1814        if (wsgi_dict) { 
     1815                wi->wsgi_harakiri = PyDict_GetItemString (wsgi_dict, "harakiri"); 
     1816                if (wi->wsgi_harakiri) { 
     1817                        fprintf (stderr, "initialized Harakiri custom handler: %p.\n", wi->wsgi_harakiri); 
     1818                } 
     1819        } 
     1820 
     1821 
     1822 
     1823#ifdef UWSGI_PROFILER 
     1824        if (uwsgi.enable_profiler) { 
     1825                pymain = PyImport_AddModule ("__main__"); 
     1826                if (!pymain) { 
     1827                        PyErr_Print (); 
     1828                        exit (1); 
     1829                } 
     1830                wi->pymain_dict = PyModule_GetDict (pymain); 
     1831                if (!wi->pymain_dict) { 
     1832                        PyErr_Print (); 
     1833                        exit (1); 
     1834                } 
     1835                if (PyDict_SetItem (wi->pymain_dict, PyString_FromFormat ("uwsgi_application__%d", id), wi->wsgi_callable)) { 
     1836                        PyErr_Print (); 
     1837                        exit (1); 
     1838                } 
     1839                if (PyDict_SetItem (wi->pymain_dict, PyString_FromFormat ("uwsgi_environ__%d", id), wi->wsgi_environ)) { 
     1840                        PyErr_Print (); 
     1841                        exit (1); 
     1842                } 
     1843                if (PyDict_SetItem (wi->pymain_dict, PyString_FromFormat ("uwsgi_spit__%d", id), wsgi_spitout)) { 
     1844                        PyErr_Print (); 
     1845                        exit (1); 
     1846                } 
     1847 
     1848                pycprof = PyImport_ImportModule ("cProfile"); 
     1849                if (!pycprof) { 
     1850                        PyErr_Print (); 
     1851                        fprintf (stderr, "trying old profile module... "); 
     1852                        pycprof = PyImport_ImportModule ("profile"); 
     1853                        if (!pycprof) { 
     1854                                fprintf (stderr, "doh!!!\n"); 
     1855                                PyErr_Print (); 
     1856                                exit (1); 
     1857                        } 
     1858                        else { 
     1859                                fprintf (stderr, "ok and set stdout to linebuf mode.\n"); 
     1860                        } 
     1861                } 
     1862                pycprof_dict = PyModule_GetDict (pycprof); 
     1863                if (!pycprof_dict) { 
     1864                        PyErr_Print (); 
     1865                        exit (1); 
     1866                } 
     1867                wi->wsgi_cprofile_run = PyDict_GetItemString (pycprof_dict, "run"); 
     1868                if (!wi->wsgi_cprofile_run) { 
     1869                        PyErr_Print (); 
     1870                        exit (1); 
     1871                } 
     1872 
     1873                wi->wsgi_args = PyTuple_New (1); 
     1874                if (PyTuple_SetItem (wi->wsgi_args, 0, PyString_FromFormat ("uwsgi_out = uwsgi_application__%d(uwsgi_environ__%d,uwsgi_spit__%d)", id, id, id))) { 
     1875                        PyErr_Print (); 
     1876                        if (uwsgi.single_interpreter == 0) { 
     1877                                Py_EndInterpreter (wi->interpreter); 
     1878                                PyThreadState_Swap (uwsgi.main_thread); 
     1879                        } 
     1880                        return -1; 
     1881                } 
     1882        } 
     1883        else { 
     1884#endif 
     1885                wi->wsgi_args = PyTuple_New (2); 
     1886                if (PyTuple_SetItem (wi->wsgi_args, 0, wi->wsgi_environ)) { 
     1887                        PyErr_Print (); 
     1888                        if (uwsgi.single_interpreter == 0) { 
     1889                                Py_EndInterpreter (wi->interpreter); 
     1890                                PyThreadState_Swap (uwsgi.main_thread); 
     1891                        } 
     1892                        return -1; 
     1893                } 
     1894                if (PyTuple_SetItem (wi->wsgi_args, 1, wsgi_spitout)) { 
     1895                        PyErr_Print (); 
     1896                        if (uwsgi.single_interpreter == 0) { 
     1897                                Py_EndInterpreter (wi->interpreter); 
     1898                                PyThreadState_Swap (uwsgi.main_thread); 
     1899                        } 
     1900                        return -1; 
     1901                } 
     1902#ifdef UWSGI_PROFILER 
     1903        } 
     1904#endif 
     1905 
     1906#ifdef UWSGI_SENDFILE 
     1907        // prepare sendfile() 
     1908        wi->wsgi_sendfile = PyCFunction_New (uwsgi_sendfile_method, NULL); 
     1909#endif 
     1910 
     1911        if (uwsgi.single_interpreter == 0) { 
     1912                PyThreadState_Swap (uwsgi.main_thread); 
     1913        } 
     1914 
     1915        memset (tmpstring, 0, 256); 
     1916        memcpy (tmpstring, wsgi_req.script_name, wsgi_req.script_name_len); 
     1917        PyDict_SetItemString (uwsgi.py_apps, tmpstring, PyInt_FromLong (id)); 
     1918        PyErr_Print (); 
     1919 
     1920        fprintf (stderr, "application %d (%s) ready\n", id, tmpstring); 
     1921 
     1922        if (id == 0) { 
     1923                fprintf (stderr, "setting default application to 0\n"); 
     1924                uwsgi.default_app = 0; 
     1925        } 
     1926        else { 
     1927                uwsgi.wsgi_cnt++; 
     1928        } 
     1929 
     1930        return id; 
     1931} 
     1932 
     1933#ifdef UWSGI_PASTE 
     1934void uwsgi_paste_config () { 
     1935        PyObject *paste_module, *paste_dict, *paste_loadapp; 
     1936        PyObject *paste_arg, *paste_app; 
     1937 
     1938        fprintf (stderr, "Loading paste environment: %s\n", uwsgi.paste); 
     1939        paste_module = PyImport_ImportModule ("paste.deploy"); 
     1940        if (!paste_module) { 
     1941                PyErr_Print (); 
     1942                exit (1); 
     1943        } 
     1944 
     1945        paste_dict = PyModule_GetDict (paste_module); 
     1946        if (!paste_dict) { 
     1947                PyErr_Print (); 
     1948                exit (1); 
     1949        } 
     1950 
     1951        paste_loadapp = PyDict_GetItemString (paste_dict, "loadapp"); 
     1952        if (!paste_loadapp) { 
     1953                PyErr_Print (); 
     1954                exit (1); 
     1955        } 
     1956 
     1957        paste_arg = PyTuple_New (1); 
     1958        if (!paste_arg) { 
     1959                PyErr_Print (); 
     1960                exit (1); 
     1961        } 
     1962 
     1963        if (PyTuple_SetItem (paste_arg, 0, PyString_FromString (uwsgi.paste))) { 
     1964                PyErr_Print (); 
     1965                exit (1); 
     1966        } 
     1967 
     1968        paste_app = PyEval_CallObject (paste_loadapp, paste_arg); 
     1969        if (!paste_app) { 
     1970                PyErr_Print (); 
     1971                exit (1); 
     1972        } 
     1973 
     1974        init_uwsgi_app (NULL, paste_app); 
     1975} 
     1976 
     1977#endif 
     1978 
     1979void uwsgi_wsgi_config () { 
     1980 
     1981        PyObject *wsgi_module, *wsgi_dict; 
     1982#ifndef PYTHREE 
     1983        PyObject *uwsgi_module, *uwsgi_dict; 
     1984#endif 
     1985        PyObject *applications; 
     1986        PyObject *app_list; 
     1987        int ret ; 
     1988        Py_ssize_t i; 
     1989        PyObject *app_mnt, *app_app; 
     1990 
     1991        wsgi_module = PyImport_ImportModule (uwsgi.wsgi_config); 
     1992        if (!wsgi_module) { 
     1993                PyErr_Print (); 
     1994                exit (1); 
     1995        } 
     1996 
     1997        wsgi_dict = PyModule_GetDict (wsgi_module); 
     1998        if (!wsgi_dict) { 
     1999                PyErr_Print (); 
     2000                exit (1); 
     2001        } 
     2002 
     2003        fprintf (stderr, "...getting the applications list from the '%s' module...\n", uwsgi.wsgi_config); 
     2004 
     2005#ifndef PYTHREE 
     2006        uwsgi_module = PyImport_ImportModule ("uwsgi"); 
     2007        if (!uwsgi_module) { 
     2008                PyErr_Print (); 
     2009                exit (1); 
     2010        } 
     2011 
     2012        uwsgi_dict = PyModule_GetDict (uwsgi_module); 
     2013        if (!uwsgi_dict) { 
     2014                PyErr_Print (); 
     2015                exit (1); 
     2016        } 
     2017 
     2018 
     2019 
     2020        applications = PyDict_GetItemString (uwsgi_dict, "applications"); 
     2021        if (!PyDict_Check (applications)) { 
     2022                fprintf (stderr, "uwsgi.applications dictionary is not defined, trying with the (deprecated) \"applications\" one...\n"); 
     2023#endif 
     2024                applications = PyDict_GetItemString (wsgi_dict, "applications"); 
     2025                if (!applications) { 
     2026                        fprintf (stderr, "applications dictionary is not defined, trying with the \"application\" callable.\n"); 
     2027                        app_app = PyDict_GetItemString (wsgi_dict, "application"); 
     2028                        if (app_app) { 
     2029                                applications = PyDict_New (); 
     2030                                if (!applications) { 
     2031                                        fprintf (stderr, "could not initialize applications dictionary\n"); 
     2032                                        exit (1); 
     2033                                } 
     2034                                if (PyDict_SetItemString (applications, "/", app_app)) { 
     2035                                        PyErr_Print (); 
     2036                                        fprintf (stderr, "unable to set default application\n"); 
     2037                                        exit (1); 
     2038                                } 
     2039                        } 
     2040                        else { 
     2041                                fprintf (stderr, "static applications not defined, you have to used the dynamic one...\n"); 
     2042                                return; 
     2043                        } 
     2044                } 
     2045#ifndef PYTHREE 
     2046        } 
     2047#endif 
     2048 
     2049        if (!PyDict_Check (applications)) { 
     2050                fprintf (stderr, "The 'applications' object must be a dictionary.\n"); 
     2051                exit (1); 
     2052        } 
     2053 
     2054        app_list = PyDict_Keys (applications); 
     2055        if (!app_list) { 
     2056                PyErr_Print (); 
     2057                exit (1); 
     2058        } 
     2059        if (PyList_Size (app_list) < 1) { 
     2060                fprintf (stderr, "You must define an app.\n"); 
     2061                exit (1); 
     2062        } 
     2063 
     2064        for (i = 0; i < PyList_Size (app_list); i++) { 
     2065                app_mnt = PyList_GetItem (app_list, i); 
     2066 
     2067                if (!PyString_Check (app_mnt)) { 
     2068                        fprintf (stderr, "the app mountpoint must be a string.\n"); 
     2069                        exit (1); 
     2070                } 
     2071 
     2072                wsgi_req.script_name = PyString_AsString (app_mnt); 
     2073                wsgi_req.script_name_len = strlen (wsgi_req.script_name); 
     2074 
     2075                app_app = PyDict_GetItem (applications, app_mnt); 
     2076 
     2077                if (!PyString_Check (app_app) && !PyFunction_Check (app_app) && !PyCallable_Check (app_app)) { 
     2078                        fprintf (stderr, "the app callable must be a string, a function or a callable. (found %s)\n", app_app->ob_type->tp_name); 
     2079                        exit (1); 
     2080                } 
     2081 
     2082                if (PyString_Check (app_app)) { 
     2083                        wsgi_req.wsgi_callable = PyString_AsString (app_app); 
     2084                        wsgi_req.wsgi_callable_len = strlen (wsgi_req.wsgi_callable); 
     2085                        fprintf (stderr, "initializing [%s => %s] app...\n", wsgi_req.script_name, wsgi_req.wsgi_callable); 
     2086                        ret = init_uwsgi_app (wsgi_dict, NULL); 
     2087                } 
     2088                else { 
     2089                        fprintf (stderr, "initializing [%s] app...\n", wsgi_req.script_name); 
     2090                        ret = init_uwsgi_app (wsgi_dict, app_app); 
     2091                } 
     2092 
     2093                if (ret < 0) { 
     2094                        fprintf (stderr, "...goodbye cruel world...\n"); 
     2095                        exit (1); 
     2096                } 
     2097                Py_DECREF (app_mnt); 
     2098                Py_DECREF (app_app); 
     2099        } 
     2100 
     2101} 
     2102 
     2103#endif 
     2104 
     2105#ifdef UNBIT 
     2106int uri_to_hex () { 
     2107        int i = 0, j = 0; 
     2108 
     2109        if (wsgi_req.uri_len < 1) { 
     2110                return 0; 
     2111        } 
     2112 
     2113        if (wsgi_req.uri_len * 2 > 8192) { 
     2114                return 0; 
     2115        } 
     2116 
     2117        for (i = 0; i < wsgi_req.uri_len; i++) { 
     2118                sprintf (tmp_filename + j, "%02X", wsgi_req.uri[i]); 
     2119                j += 2; 
     2120        } 
     2121 
     2122        return j; 
     2123} 
     2124#endif 
     2125 
     2126#ifdef UWSGI_EMBEDDED 
     2127void init_uwsgi_embedded_module () { 
     2128        PyObject *new_uwsgi_module, *zero; 
     2129        int i; 
     2130 
     2131        /* initialize for stats */ 
     2132        uwsgi.workers_tuple = PyTuple_New (uwsgi.numproc); 
     2133        for (i = 0; i < uwsgi.numproc; i++) { 
     2134                zero = PyDict_New (); 
     2135                Py_INCREF (zero); 
     2136                PyTuple_SetItem (uwsgi.workers_tuple, i, zero); 
     2137        } 
     2138 
     2139 
     2140 
     2141        new_uwsgi_module = Py_InitModule ("uwsgi", null_methods); 
     2142        if (new_uwsgi_module == NULL) { 
     2143                fprintf (stderr, "could not initialize the uwsgi python module\n"); 
     2144                exit (1); 
     2145        } 
     2146 
     2147        uwsgi.embedded_dict = PyModule_GetDict (new_uwsgi_module); 
     2148        if (!uwsgi.embedded_dict) { 
     2149                fprintf (stderr, "could not get uwsgi module __dict__\n"); 
     2150                exit (1); 
     2151        } 
     2152 
     2153        if (PyDict_SetItemString (uwsgi.embedded_dict, "SPOOL_RETRY", PyInt_FromLong (17))) { 
     2154                PyErr_Print (); 
     2155                exit (1); 
     2156        } 
     2157 
     2158        if (PyDict_SetItemString (uwsgi.embedded_dict, "numproc", PyInt_FromLong (uwsgi.numproc))) { 
     2159                PyErr_Print (); 
     2160                exit (1); 
     2161        } 
     2162 
     2163#ifdef UNBIT 
     2164        if (PyDict_SetItemString (uwsgi.embedded_dict, "unbit", Py_True)) { 
     2165#else 
     2166        if (PyDict_SetItemString (uwsgi.embedded_dict, "unbit", Py_None)) { 
     2167#endif 
     2168                PyErr_Print (); 
     2169                exit (1); 
     2170        } 
     2171 
     2172        if (PyDict_SetItemString (uwsgi.embedded_dict, "buffer_size", PyInt_FromLong (uwsgi.buffer_size))) { 
     2173                PyErr_Print (); 
     2174                exit (1); 
     2175        } 
     2176 
     2177        if (PyDict_SetItemString (uwsgi.embedded_dict, "started_on", PyInt_FromLong (uwsgi.start_tv.tv_sec))) { 
     2178                PyErr_Print (); 
     2179                exit (1); 
     2180        } 
     2181 
     2182        if (PyDict_SetItemString (uwsgi.embedded_dict, "start_response", wsgi_spitout)) { 
     2183                PyErr_Print (); 
     2184                exit (1); 
     2185        } 
     2186 
     2187        if (PyDict_SetItemString (uwsgi.embedded_dict, "fastfuncs", PyList_New (256))) { 
     2188                PyErr_Print (); 
     2189                exit (1); 
     2190        } 
     2191 
     2192 
     2193        if (PyDict_SetItemString (uwsgi.embedded_dict, "applist", uwsgi.py_apps)) { 
     2194                PyErr_Print (); 
     2195                exit (1); 
     2196        } 
     2197 
     2198        if (PyDict_SetItemString (uwsgi.embedded_dict, "applications", Py_None)) { 
     2199                PyErr_Print (); 
     2200                exit (1); 
     2201        } 
     2202 
     2203        uwsgi.embedded_args = PyTuple_New (2); 
     2204        if (!uwsgi.embedded_args) { 
     2205                PyErr_Print (); 
     2206                exit (1); 
     2207        } 
     2208 
     2209        if (PyDict_SetItemString (uwsgi.embedded_dict, "message_manager_marshal", Py_None)) { 
     2210                PyErr_Print (); 
     2211                exit (1); 
     2212        } 
     2213 
     2214        uwsgi.fastfuncslist = PyDict_GetItemString (uwsgi.embedded_dict, "fastfuncs"); 
     2215        if (!uwsgi.fastfuncslist) { 
     2216                PyErr_Print (); 
     2217                exit (1); 
     2218        } 
     2219 
     2220        init_uwsgi_module_advanced (new_uwsgi_module); 
     2221 
     2222#ifdef UWSGI_SPOOLER 
     2223        if (spool_dir != NULL) { 
     2224                init_uwsgi_module_spooler (new_uwsgi_module); 
     2225        } 
     2226#endif 
     2227 
     2228 
     2229        if (uwsgi.sharedareasize > 0 && uwsgi.sharedarea) { 
     2230                init_uwsgi_module_sharedarea (new_uwsgi_module); 
     2231        } 
     2232} 
     2233#endif 
     2234 
     2235#ifdef UWSGI_SPOOLER 
     2236pid_t spooler_start (int serverfd, PyObject * uwsgi_module) { 
     2237        pid_t pid; 
     2238 
     2239        pid = fork (); 
     2240        if (pid < 0) { 
     2241                perror ("fork()"); 
     2242                exit (1); 
     2243        } 
     2244        else if (pid == 0) { 
     2245                close (serverfd); 
     2246                spooler (uwsgi_module); 
     2247        } 
     2248        else if (pid > 0) { 
     2249                fprintf (stderr, "spawned the uWSGI spooler on dir %s with pid %d\n", spool_dir, pid); 
     2250        } 
     2251 
     2252        return pid; 
     2253} 
     2254#endif 
     2255 
     2256void manage_opt(int i, char *optarg) { 
     2257 
    7192258                switch (i) { 
    7202259#ifndef ROCK_SOLID 
     
    7242263                        break; 
    7252264                case LONG_ARGS_UDP: 
    726                         udp_socket = optarg; 
     2265                        uwsgi.udp_socket = optarg; 
    7272266                        uwsgi.master_process = 1; 
    7282267                        break; 
     
    7362275                        uwsgi.uid = atoi (optarg); 
    7372276                        break; 
     2277#ifdef UWSGI_ERLANG 
     2278                case LONG_ARGS_ERLANG: 
     2279                        uwsgi.erlang_node = optarg; 
     2280                        break; 
     2281#endif 
    7382282                case LONG_ARGS_PYTHONPATH: 
    7392283                        if (uwsgi.python_path_cnt < 63) { 
     
    7462290                        break; 
    7472291                case LONG_ARGS_LIMIT_AS: 
    748                         rl.rlim_cur = (atoi (optarg)) * 1024 * 1024; 
    749                         rl.rlim_max = rl.rlim_cur; 
     2292                        uwsgi.rl.rlim_cur = (atoi (optarg)) * 1024 * 1024; 
     2293                        uwsgi.rl.rlim_max = uwsgi.rl.rlim_cur; 
    7502294                        break; 
    7512295#endif 
     
    7732317                        uwsgi.options[UWSGI_OPTION_LOGGING] = 0; 
    7742318                        break; 
    775 #ifndef ROCK_SOLID 
     2319#ifdef UWSGI_SPOOLER 
    7762320                case 'Q': 
    7772321                        spool_dir = optarg; 
     
    8082352#ifndef UNBIT 
    8092353                case 'd': 
    810                         if (!is_a_reload) { 
     2354                        if (!uwsgi.is_a_reload) { 
    8112355                                daemonize (optarg); 
    8122356                        } 
    8132357                        break; 
    8142358                case 's': 
    815                         socket_name = optarg; 
    816                         break; 
    817 #ifndef ROCK_SOLID 
     2359                        uwsgi.socket_name = optarg; 
     2360                        break; 
     2361#ifdef UWSGI_XML 
    8182362                case 'x': 
    8192363                        uwsgi.xml_config = optarg; 
     
    9302474\t--limit-as <MB>\t\t\tlimit the address space of processes to MB megabytes\n\ 
    9312475\t--udp <ip:port>\t\t\tbind master process to udp socket on ip:port\n\ 
    932 \t-d|--daemonize <logfile>\tdaemonize and log into <logfile>\n", argv[0]); 
     2476\t-d|--daemonize <logfile>\tdaemonize and log into <logfile>\n", uwsgi.binary_path); 
    9332477                        exit (1); 
    9342478                case 0: 
     
    9402484        } 
    9412485 
    942 #ifndef UNBIT 
    943 #ifndef ROCK_SOLID 
    944         if (uwsgi.options[UWSGI_OPTION_CGI_MODE] == 0) { 
    945 #endif 
    946 #endif 
    947                 if (uwsgi.test_module == NULL) { 
    948                         fprintf (stderr, "*** Starting uWSGI (%dbit) on [%.*s] ***\n", (int) (sizeof (void *)) * 8, 24, ctime ((const time_t *) &uwsgi.start_tv.tv_sec)); 
    949                 } 
    950 #ifndef UNBIT 
    951 #ifndef ROCK_SOLID 
    952         } 
    953         else { 
    954                 fprintf (stderr, "*** Starting uWSGI (CGI mode) (%dbit) on [%.*s] ***\n", (int) (sizeof (void *)) * 8, 24, ctime ((const time_t *) &uwsgi.start_tv.tv_sec)); 
    955         } 
    956 #endif 
    957 #endif 
    958  
    959 #ifdef __BIG_ENDIAN__ 
    960         fprintf (stderr, "*** big endian arch detected ***\n"); 
    961 #endif 
    962  
    963 #ifdef PYTHREE 
    964         fprintf (stderr, "*** Warning Python3.x support is experimental, do not use it in production environment ***\n"); 
    965 #endif 
    966  
    967         fprintf (stderr, "Python version: %s\n", Py_GetVersion ()); 
    968  
    969 #ifndef UNBIT 
    970         if (!getuid ()) { 
    971                 fprintf (stderr, "uWSGI running as root, you can use --uid/--gid/--chroot options\n"); 
    972                 if (uwsgi.chroot) { 
    973                         fprintf (stderr, "chroot() to %s\n", uwsgi.chroot); 
    974                         if (chroot (uwsgi.chroot)) { 
    975                                 perror ("chroot()"); 
    976                                 exit (1); 
    977                         } 
    978 #ifdef __linux__ 
    979                         if (uwsgi.options[UWSGI_OPTION_MEMORY_DEBUG]) { 
    980                                 fprintf (stderr, "*** Warning, on linux system you have to bind-mount the /proc fs in your chroot to get memory debug/report.\n"); 
    981                         } 
    982 #endif 
    983                 } 
    984                 if (uwsgi.gid) { 
    985                         fprintf (stderr, "setgid() to %d\n", uwsgi.gid); 
    986                         if (setgid (uwsgi.gid)) { 
    987                                 perror ("setgid()"); 
    988                                 exit (1); 
    989                         } 
    990                 } 
    991                 if (uwsgi.uid) { 
    992                         fprintf (stderr, "setuid() to %d\n", uwsgi.uid); 
    993                         if (setuid (uwsgi.uid)) { 
    994                                 perror ("setuid()"); 
    995                                 exit (1); 
    996                         } 
    997                 } 
    998  
    999                 if (!getuid()) { 
    1000                         fprintf(stderr," *** WARNING: you are running uWSGI as root !!! (use the --uid flag) *** \n"); 
    1001                 } 
    1002         } 
    1003         else { 
    1004                 if (uwsgi.chroot) { 
    1005                         fprintf (stderr, "cannot chroot() as non-root user\n"); 
    1006                         exit (1); 
    1007                 } 
    1008                 if (uwsgi.gid) { 
    1009                         fprintf (stderr, "cannot setgid() as non-root user\n"); 
    1010                         exit (1); 
    1011                 } 
    1012                 if (uwsgi.uid) { 
    1013                         fprintf (stderr, "cannot setuid() as non-root user\n"); 
    1014                         exit (1); 
    1015                 } 
    1016         } 
    1017  
    1018          
    1019  
    1020 #endif 
    1021  
    1022 #ifndef UNBIT 
    1023         if (rl.rlim_max > 0) { 
    1024                 fprintf (stderr, "limiting address space of processes...\n"); 
    1025                 if (setrlimit (RLIMIT_AS, &rl)) { 
    1026                         perror ("setrlimit()"); 
    1027                 } 
    1028         } 
    1029 #endif 
    1030  
    1031         if (!getrlimit (RLIMIT_AS, &rl)) { 
    1032 #ifndef UNBIT 
    1033                 // check for overflow 
    1034                 if ((sizeof (void *) == 4 && (uint32_t) rl.rlim_max < UINT32_MAX) || (sizeof (void *) == 8 && (uint64_t) rl.rlim_max < UINT64_MAX)) { 
    1035 #endif 
    1036                         fprintf (stderr, "your process address space limit is %lld bytes (%lld MB)\n", (long long) rl.rlim_max, (long long) rl.rlim_max / 1024 / 1024); 
    1037 #ifndef UNBIT 
    1038                 } 
    1039 #endif 
    1040         } 
    1041  
    1042         uwsgi.page_size = getpagesize (); 
    1043         fprintf (stderr, "your memory page size is %d bytes\n", uwsgi.page_size); 
    1044  
    1045 #ifndef UNBIT 
    1046         fprintf (stderr, "your server socket listen backlog is limited to %d connections\n", uwsgi.listen_queue); 
    1047 #endif 
    1048  
    1049         if (uwsgi.synclog) { 
    1050                 fprintf (stderr, "allocating a memory page for synced logging.\n"); 
    1051                 uwsgi.sync_page = malloc (uwsgi.page_size); 
    1052                 if (!uwsgi.sync_page) { 
    1053                         perror ("malloc()"); 
    1054                         exit (1); 
    1055                 } 
    1056         } 
    1057  
    1058         if (uwsgi.pyhome != NULL) { 
    1059                 fprintf (stderr, "Setting PythonHome to %s...\n", uwsgi.pyhome); 
    1060 #ifdef PYTHREE 
    1061                 wchar_t *wpyhome; 
    1062                 wpyhome = malloc ((sizeof (wchar_t) * strlen (uwsgi.pyhome)) + 2); 
    1063                 if (!wpyhome) { 
    1064                         perror ("malloc()"); 
    1065                         exit (1); 
    1066                 } 
    1067                 mbstowcs (wpyhome, uwsgi.pyhome, strlen (uwsgi.pyhome)); 
    1068                 Py_SetPythonHome (wpyhome); 
    1069                 free (wpyhome); 
    1070 #else 
    1071                 Py_SetPythonHome (uwsgi.pyhome); 
    1072 #endif 
    1073         } 
    1074  
    1075  
    1076  
    1077  
    1078 #ifdef PYTHREE 
    1079         wchar_t pname[6]; 
    1080         mbstowcs (pname, "uWSGI", 6); 
    1081         Py_SetProgramName (pname); 
    1082 #else 
    1083         Py_SetProgramName ("uWSGI"); 
    1084 #endif 
    1085  
    1086  
    1087         Py_Initialize (); 
    1088  
    1089         pyargv[0] = "uwsgi"; 
    1090  
    1091         if (uwsgi.pyargv != NULL) { 
    1092                 char *ap; 
    1093                 while ((ap = strsep (&uwsgi.pyargv, " \t")) != NULL) { 
    1094                         if (*ap != '\0') { 
    1095                                 pyargv[pyargc] = ap; 
    1096                                 pyargc++; 
    1097                         } 
    1098                         if (pyargc + 1 > MAX_PYARGV) 
    1099                                 break; 
    1100                 } 
    1101         } 
    1102  
    1103         PySys_SetArgv (pyargc, pyargv); 
    1104  
    1105  
    1106 #ifndef ROCK_SOLID 
    1107         uwsgi.py_apps = PyDict_New (); 
    1108         if (!uwsgi.py_apps) { 
    1109                 PyErr_Print (); 
    1110                 exit (1); 
    1111         } 
    1112  
    1113 #endif 
    1114  
    1115  
    1116         wsgi_spitout = PyCFunction_New (uwsgi_spit_method, NULL); 
    1117         wsgi_writeout = PyCFunction_New (uwsgi_write_method, NULL); 
    1118  
    1119 #ifndef PYTHREE 
    1120 #ifndef ROCK_SOLID 
    1121         uwsgi_module = Py_InitModule ("uwsgi", null_methods); 
    1122         if (uwsgi_module == NULL) { 
    1123                 fprintf (stderr, "could not initialize the uwsgi python module\n"); 
    1124                 exit (1); 
    1125         } 
    1126         if (uwsgi.sharedareasize > 0) { 
    1127 #ifndef __OpenBSD__ 
    1128                 uwsgi.sharedareamutex = mmap (NULL, sizeof (pthread_mutexattr_t) + sizeof (pthread_mutex_t), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0); 
    1129                 if (!uwsgi.sharedareamutex) { 
    1130                         perror ("mmap()"); 
    1131                         exit (1); 
    1132                 } 
    1133 #else 
    1134                 fprintf (stderr, "***WARNING*** the sharedarea on OpenBSD is not SMP-safe. Beware of race conditions !!!\n"); 
    1135 #endif 
    1136                 uwsgi.sharedarea = mmap (NULL, uwsgi.page_size * uwsgi.sharedareasize, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0); 
    1137                 if (uwsgi.sharedarea) { 
    1138                         fprintf (stderr, "shared area mapped at %p, you can access it with uwsgi.sharedarea* functions.\n", uwsgi.sharedarea); 
    1139  
    1140 #ifdef __APPLE__ 
    1141                         memset (uwsgi.sharedareamutex, 0, sizeof (OSSpinLock)); 
    1142 #else 
    1143 #ifndef __OpenBSD__ 
    1144                         if (pthread_mutexattr_init ((pthread_mutexattr_t *) uwsgi.sharedareamutex)) { 
    1145                                 fprintf (stderr, "unable to allocate mutexattr structure\n"); 
    1146                                 exit (1); 
    1147                         } 
    1148                         if (pthread_mutexattr_setpshared ((pthread_mutexattr_t *) uwsgi.sharedareamutex, PTHREAD_PROCESS_SHARED)) { 
    1149                                 fprintf (stderr, "unable to share mutex\n"); 
    1150                                 exit (1); 
    1151                         } 
    1152                         if (pthread_mutex_init ((pthread_mutex_t *) uwsgi.sharedareamutex + sizeof (pthread_mutexattr_t), (pthread_mutexattr_t *) uwsgi.sharedareamutex)) { 
    1153                                 fprintf (stderr, "unable to initialize mutex\n"); 
    1154                                 exit (1); 
    1155                         } 
    1156 #endif 
    1157 #endif 
    1158  
    1159                 } 
    1160                 else { 
    1161                         perror ("mmap()"); 
    1162                         exit (1); 
    1163                 } 
    1164  
    1165         } 
    1166  
    1167         init_uwsgi_embedded_module (); 
    1168 #endif 
    1169 #endif 
    1170  
    1171  
    1172  
    1173 #ifdef ROCK_SOLID 
    1174  
    1175  
    1176         wi = malloc (sizeof (struct uwsgi_app)); 
    1177         if (wi == NULL) { 
    1178                 perror ("malloc()"); 
    1179                 exit (1); 
    1180         } 
    1181         memset (wi, 0, sizeof (struct uwsgi_app)); 
    1182  
    1183         // load wsgi module/script 
    1184         for (i = optind; i < argc; i++) { 
    1185                 init_uwsgi_vars (); 
    1186                 wi->wsgi_module = PyImport_ImportModule (argv[i]); 
    1187                 if (!wi->wsgi_module) { 
    1188                         PyErr_Print (); 
    1189                         exit (1); 
    1190                 } 
    1191                 wi->wsgi_dict = PyModule_GetDict (wi->wsgi_module); 
    1192                 if (!wi->wsgi_dict) { 
    1193                         PyErr_Print (); 
    1194                         exit (1); 
    1195                 } 
    1196                 wi->wsgi_callable = PyDict_GetItemString (wi->wsgi_dict, "application"); 
    1197                 if (!wi->wsgi_callable) { 
    1198                         PyErr_Print (); 
    1199                         exit (1); 
    1200                 } 
    1201                 wi->wsgi_environ = PyDict_New (); 
    1202                 if (!wi->wsgi_environ) { 
    1203                         PyErr_Print (); 
    1204                         exit (1); 
    1205                 } 
    1206  
    1207                 wi->wsgi_harakiri = PyDict_GetItemString (wi->wsgi_dict, "harakiri"); 
    1208  
    1209                 wi->wsgi_args = PyTuple_New (2); 
    1210                 if (!wi->wsgi_args) { 
    1211                         PyErr_Print (); 
    1212                         exit (1); 
    1213                 } 
    1214                 if (PyTuple_SetItem (wi->wsgi_args, 0, wi->wsgi_environ)) { 
    1215                         PyErr_Print (); 
    1216                         exit (1); 
    1217                 } 
    1218                 if (PyTuple_SetItem (wi->wsgi_args, 1, wsgi_spitout)) { 
    1219                         PyErr_Print (); 
    1220                         exit (1); 
    1221                 } 
    1222                 break; 
    1223         } 
    1224  
    1225         if (!wi->wsgi_module) { 
    1226                 fprintf (stderr, "unable to find the wsgi script. Have you specified it ?\n"); 
    1227                 exit (1); 
    1228         } 
    1229 #endif 
    1230  
    1231 #ifndef ROCK_SOLID 
    1232         Py_OptimizeFlag = uwsgi.py_optimize; 
    1233  
    1234         uwsgi.main_thread = PyThreadState_Get (); 
    1235  
    1236  
    1237         if (uwsgi.has_threads) { 
    1238                 PyEval_InitThreads (); 
    1239                 fprintf (stderr, "threads support enabled\n"); 
    1240         } 
    1241  
    1242 #endif 
    1243  
    1244         if (!no_server) { 
    1245 #ifndef UNBIT 
    1246                 if (socket_name != NULL && !is_a_reload) { 
    1247 #ifdef SCTP 
    1248                         if (!strncmp (socket_name, "sctp:", 5)) { 
    1249                                 char *sctp_port = strchr (socket_name + 5, ':'); 
    1250                                 if (sctp_port == NULL) { 
    1251                                         fprintf (stderr, "invalid SCTP port ! syntax: sctp:ip1,ip2,ipN:port\n"); 
    1252                                         exit (1); 
    1253                                 } 
    1254                                 uwsgi.serverfd = bind_to_sctp (socket_name + 5, uwsgi.listen_queue, sctp_port); 
    1255                                 i_am_sctp = 1; 
    1256                         } 
    1257                         else { 
    1258 #endif 
    1259                                 char *tcp_port = strchr (socket_name, ':'); 
    1260                                 if (tcp_port == NULL) { 
    1261                                         uwsgi.serverfd = bind_to_unix (socket_name, uwsgi.listen_queue, uwsgi.chmod_socket, uwsgi.abstract_socket); 
    1262                                 } 
    1263                                 else { 
    1264                                         uwsgi.serverfd = bind_to_tcp (socket_name, uwsgi.listen_queue, tcp_port); 
    1265                                 } 
    1266  
    1267                                 if (uwsgi.serverfd < 0) { 
    1268                                         fprintf (stderr, "unable to create the server socket.\n"); 
    1269                                         exit (1); 
    1270                                 } 
    1271 #ifdef SCTP 
    1272                         } 
    1273 #endif 
    1274                 } 
    1275 #endif 
    1276  
    1277                 socket_type_len = sizeof (int); 
    1278                 if (getsockopt (uwsgi.serverfd, SOL_SOCKET, SO_TYPE, &socket_type, &socket_type_len)) { 
    1279                         perror ("getsockopt()"); 
    1280                         fprintf(stderr, "The -s/--socket option is missing and stdin is not a socket.\n"); 
    1281                         exit (1); 
    1282                 } 
    1283  
    1284         } 
    1285  
    1286  
    1287  
    1288 #ifndef ROCK_SOLID 
    1289         if (uwsgi.single_interpreter == 1) { 
    1290                 init_uwsgi_vars (); 
    1291         } 
    1292  
    1293         memset (uwsgi.wsgi_apps, 0, sizeof (uwsgi.wsgi_apps)); 
    1294  
    1295  
    1296 #endif 
    1297  
    1298  
    1299  
    1300         uwsgi.poll.events = POLLIN; 
    1301  
    1302         memset (&wsgi_req, 0, sizeof (struct wsgi_request)); 
    1303  
    1304         /* shared area for workers */ 
    1305         uwsgi.workers = (struct uwsgi_worker *) mmap (NULL, sizeof (struct uwsgi_worker) * uwsgi.maxworkers + 1, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0); 
    1306         if (!uwsgi.workers) { 
    1307                 perror ("mmap()"); 
    1308                 exit (1); 
    1309         } 
    1310         memset (uwsgi.workers, 0, sizeof (struct uwsgi_worker) * uwsgi.maxworkers + 1); 
    1311  
    1312         uwsgi.mypid = getpid (); 
    1313         masterpid = uwsgi.mypid; 
    1314  
    1315 #ifndef ROCK_SOLID 
    1316 #ifndef UNBIT 
    1317         if (uwsgi.pidfile) { 
    1318                 fprintf (stderr, "writing pidfile to %s\n", uwsgi.pidfile); 
    1319                 pidfile = fopen (uwsgi.pidfile, "w"); 
    1320                 if (!pidfile) { 
    1321                         perror ("fopen"); 
    1322                         exit (1); 
    1323                 } 
    1324                 if (fprintf (pidfile, "%d\n", masterpid) < 0) { 
    1325                         fprintf (stderr, "could not write pidfile.\n"); 
    1326                 } 
    1327                 fclose (pidfile); 
    1328         } 
    1329 #endif 
    1330 #endif 
    1331  
    1332         if (uwsgi.buffer_size > 65536) { 
    1333                 fprintf (stderr, "invalid buffer size.\n"); 
    1334                 exit (1); 
    1335         } 
    1336         buffer = malloc (uwsgi.buffer_size); 
    1337         if (buffer == NULL) { 
    1338                 fprintf (stderr, "unable to allocate memory for buffer.\n"); 
    1339                 exit (1); 
    1340         } 
    1341  
    1342         fprintf (stderr, "request/response buffer (%d bytes) allocated.\n", uwsgi.buffer_size); 
    1343  
    1344         /* save the masterpid */ 
    1345         uwsgi.workers[0].pid = masterpid; 
    1346  
    1347         uwsgi.workers[0].current_workers = uwsgi.numproc; 
    1348  
    1349         fprintf(stderr,"initializing hooks..."); 
    1350  
    1351         uwsgi.hooks[0] = uwsgi_request_wsgi ;  
    1352         uwsgi.after_hooks[0] = uwsgi_after_request_wsgi ;  
    1353  
    1354         uwsgi.hooks[UWSGI_MODIFIER_ADMIN_REQUEST] = uwsgi_request_admin ; //10 
    1355         uwsgi.hooks[UWSGI_MODIFIER_SPOOL_REQUEST] = uwsgi_request_spooler ; //17 
    1356         uwsgi.hooks[UWSGI_MODIFIER_FASTFUNC] = uwsgi_request_fastfunc ; //26 
    1357  
    1358         uwsgi.hooks[UWSGI_MODIFIER_MANAGE_PATH_INFO] = uwsgi_request_wsgi ; // 30 
    1359         uwsgi.after_hooks[UWSGI_MODIFIER_MANAGE_PATH_INFO] = uwsgi_after_request_wsgi; // 30 
    1360  
    1361         uwsgi.hooks[UWSGI_MODIFIER_MESSAGE_MARSHAL] = uwsgi_request_marshal ; //33 
    1362         uwsgi.hooks[UWSGI_MODIFIER_PING] = uwsgi_request_ping ; //100 
    1363  
    1364         fprintf(stderr,"done.\n"); 
    1365  
    1366  
    1367 #ifndef ROCK_SOLID 
    1368         if (uwsgi.wsgi_config != NULL) { 
    1369                 uwsgi_wsgi_config (); 
    1370         } 
    1371 #endif 
    1372  
    1373 #ifndef UNBIT 
    1374 #ifndef ROCK_SOLID 
    1375         else if (uwsgi.xml_config != NULL) { 
    1376                 uwsgi_xml_config (); 
    1377         } 
    1378 #endif 
    1379 #endif 
    1380  
    1381 #ifndef ROCK_SOLID 
    1382         else if (uwsgi.paste != NULL) { 
    1383                 uwsgi_paste_config (); 
    1384         } 
    1385 #endif 
    1386  
    1387         if (uwsgi.test_module != NULL) { 
    1388                 if (PyImport_ImportModule (uwsgi.test_module)) { 
    1389                         exit (0); 
    1390                 } 
    1391                 exit (1); 
    1392         } 
    1393  
    1394  
    1395  
    1396 #ifndef UNBIT 
    1397 #ifndef ROCK_SOLID 
    1398         if (no_server) { 
    1399                 fprintf (stderr, "no-server mode requested. Goodbye.\n"); 
    1400                 exit (0); 
    1401         } 
    1402 #endif 
    1403 #endif 
    1404  
    1405         /* preforking() */ 
    1406         if (uwsgi.master_process) { 
    1407                 if (is_a_reload) { 
    1408                         fprintf (stderr, "gracefully (RE)spawned uWSGI master process (pid: %d)\n", uwsgi.mypid); 
    1409                 } 
    1410                 else { 
    1411                         fprintf (stderr, "spawned uWSGI master process (pid: %d)\n", uwsgi.mypid); 
    1412                 } 
    1413         } 
    1414  
    1415 #ifdef UNBIT 
    1416         if (single_app_mode == 1) { 
    1417                 wsgi_req.wsgi_script = getenv ("UWSGI_SCRIPT"); 
    1418                 if (wsgi_req.wsgi_script) { 
    1419                         wsgi_req.wsgi_script_len = strlen (wsgi_req.wsgi_script); 
    1420                 } 
    1421                 else { 
    1422                         fprintf (stderr, "UWSGI_SCRIPT env var not set !\n"); 
    1423                         exit (1); 
    1424                 } 
    1425  
    1426                 init_uwsgi_app (NULL, NULL); 
    1427         } 
    1428 #endif 
    1429  
    1430 #ifndef ROCK_SOLID 
    1431 #ifndef PYTHREE 
    1432         if (spool_dir != NULL) { 
    1433                 uwsgi.workers[0].spooler_pid = spooler_start (uwsgi.serverfd, uwsgi_module); 
    1434         } 
    1435 #endif 
    1436 #endif 
    1437  
    1438  
    1439         if (!uwsgi.master_process) { 
    1440                 if (uwsgi.numproc == 1) { 
    1441                         fprintf (stderr, "spawned uWSGI worker 1 (and the only) (pid: %d)\n", masterpid); 
    1442                 } 
    1443                 else { 
    1444                         fprintf (stderr, "spawned uWSGI worker 1 (pid: %d)\n", masterpid); 
    1445                 } 
    1446                 uwsgi.workers[1].pid = masterpid; 
    1447                 uwsgi.workers[1].id = 1; 
    1448                 uwsgi.workers[1].last_spawn = time (NULL); 
    1449                 uwsgi.workers[1].manage_next_request = 1; 
    1450                 uwsgi.mywid = 1; 
    1451                 gettimeofday (&last_respawn, NULL); 
    1452                 respawn_delta = last_respawn.tv_sec; 
    1453         } 
    1454  
    1455  
    1456                 for (i = 2-uwsgi.master_process ; i < uwsgi.numproc + 1; i++) { 
    1457                         /* let the worker know his worker_id (wid) */ 
    1458                         pid = fork (); 
    1459                         if (pid == 0) { 
    1460                                 uwsgi.mypid = getpid (); 
    1461                                 uwsgi.workers[i].pid = uwsgi.mypid; 
    1462                                 uwsgi.workers[i].id = i; 
    1463                                 uwsgi.workers[i].last_spawn = time (NULL); 
    1464                                 uwsgi.workers[i].manage_next_request = 1; 
    1465                                 uwsgi.mywid = i; 
    1466                                 if (uwsgi.serverfd != 0 && uwsgi.master_process == 1) { 
    1467                                         /* close STDIN for workers */ 
    1468                                         close (0); 
    1469                                 } 
    1470                                 break; 
    1471                         } 
    1472                         else if (pid < 1) { 
    1473                                 perror ("fork()"); 
    1474                                 exit (1); 
    1475                         } 
    1476                         else { 
    1477                                 fprintf (stderr, "spawned uWSGI worker %d (pid: %d)\n", i, pid); 
    1478                                 gettimeofday (&last_respawn, NULL); 
    1479                                 respawn_delta = last_respawn.tv_sec; 
    1480                         } 
    1481                 } 
    1482  
    1483  
    1484         if (getpid () == masterpid && uwsgi.master_process == 1) { 
    1485                 /* route signals to workers... */ 
    1486                 signal (SIGHUP, (void *) &grace_them_all); 
    1487                 signal (SIGTERM, (void *) &reap_them_all); 
    1488                 signal (SIGINT, (void *) &kill_them_all); 
    1489                 signal (SIGQUIT, (void *) &kill_them_all); 
    1490                 /* used only to avoid human-errors */ 
    1491 #ifndef ROCK_SOLID 
    1492 #ifndef UNBIT 
    1493                 signal (SIGUSR1, (void *) &stats); 
    1494 #endif 
    1495 #endif 
    1496  
    1497                 if (udp_socket) { 
    1498                         udp_poll.fd = bind_to_udp (udp_socket); 
    1499                         if (udp_poll.fd < 0) { 
    1500                                 fprintf (stderr, "unable to bind to udp socket. SNMP and cluster management services will be disabled.\n"); 
    1501                         } 
    1502                         else { 
    1503                                 fprintf (stderr, "UDP server enabled.\n"); 
    1504                                 udp_poll.events = POLLIN; 
    1505                         } 
    1506                 } 
    1507                 for (;;) { 
    1508                         if (ready_to_die >= uwsgi.numproc && uwsgi.to_hell) { 
    1509 #ifndef ROCK_SOLID 
    1510                                 if (spool_dir && uwsgi.workers[0].spooler_pid > 0) { 
    1511                                         kill (uwsgi.workers[0].spooler_pid, SIGKILL); 
    1512                                 } 
    1513  
    1514 #endif 
    1515                                 fprintf (stderr, "goodbye to uWSGI.\n"); 
    1516                                 exit (0); 
    1517                         } 
    1518                         if (ready_to_reload >= uwsgi.numproc && uwsgi.to_heaven) { 
    1519 #ifndef ROCK_SOLID 
    1520                                 if (spool_dir && uwsgi.workers[0].spooler_pid > 0) { 
    1521                                         kill (uwsgi.workers[0].spooler_pid, SIGKILL); 
    1522                                 } 
    1523 #endif 
    1524                                 fprintf (stderr, "binary reloading uWSGI...\n"); 
    1525                                 if (chdir (cwd)) { 
    1526                                         perror ("chdir()"); 
    1527                                         exit (1); 
    1528                                 } 
    1529                                 /* check fd table (a module can obviosly open some fd on initialization...) */ 
    1530                                 fprintf (stderr, "closing all fds > 2 (_SC_OPEN_MAX = %ld)...\n", sysconf (_SC_OPEN_MAX)); 
    1531                                 for (i = 3; i < sysconf (_SC_OPEN_MAX); i++) { 
    1532                                         if (i == uwsgi.serverfd) { 
    1533                                                 continue; 
    1534                                         } 
    1535                                         close (i); 
    1536                                 } 
    1537                                 if (uwsgi.serverfd != 3) { 
    1538                                         if (dup2 (uwsgi.serverfd, 3) < 0) { 
    1539                                                 perror ("dup2()"); 
    1540                                                 exit (1); 
    1541                                         } 
    1542                                 } 
    1543                                 fprintf (stderr, "running %s\n", binary_path); 
    1544                                 strcpy (argv[0], binary_path); 
    1545                                 execve (binary_path, argv, environ); 
    1546                                 perror ("execve()"); 
    1547                                 exit (1); 
    1548                         } 
    1549                         diedpid = waitpid (WAIT_ANY, &waitpid_status, WNOHANG); 
    1550                         if (diedpid == -1) { 
    1551                                 perror ("waitpid()"); 
    1552                                 /* here is better to reload all the uWSGI stack */ 
    1553                                 fprintf (stderr, "something horrible happened...\n"); 
    1554                                 reap_them_all (); 
    1555                                 exit (1); 
    1556                         } 
    1557                         else if (diedpid == 0) { 
    1558                                 /* PLEASE, do not run python threads in the master process, you can potentially destroy the world, 
    1559                                    we support this for hyperultramegagodprogrammer and systems 
    1560                                  */ 
    1561 #ifndef ROCK_SOLID 
    1562                                 if (uwsgi.has_threads && uwsgi.options[UWSGI_OPTION_THREADS] == 1) { 
    1563                                         uwsgi._save = PyEval_SaveThread (); 
    1564                                         uwsgi.i_have_gil = 0; 
    1565                                 } 
    1566 #endif 
    1567                                 /* all processes ok, doing status scan after N seconds */ 
    1568                                 check_interval.tv_sec = uwsgi.options[UWSGI_OPTION_MASTER_INTERVAL]; 
    1569                                 if (!check_interval.tv_sec) 
    1570                                         check_interval.tv_sec = 1; 
    1571                                  
    1572                                 if (udp_socket && udp_poll.fd >= 0) { 
    1573                                         rlen = poll (&udp_poll, 1, check_interval.tv_sec * 1000); 
    1574                                         if (rlen < 0) { 
    1575                                                 perror ("poll()"); 
    1576                                         } 
    1577                                         else if (rlen > 0) { 
    1578                                                 udp_len = sizeof (udp_client); 
    1579                                                 rlen = recvfrom (udp_poll.fd, buffer, uwsgi.buffer_size, 0, (struct sockaddr *) &udp_client, &udp_len); 
    1580                                                 if (rlen < 0) { 
    1581                                                         perror ("recvfrom()"); 
    1582                                                 } 
    1583                                                 else if (rlen > 0) { 
    1584                                                         memset (udp_client_addr, 0, 16); 
    1585                                                         if (inet_ntop (AF_INET, &udp_client, udp_client_addr, 16)) { 
    1586                                                                 fprintf (stderr, "received udp packet of %d bytes from %s:%d\n", rlen, udp_client_addr, ntohs (udp_client.sin_port)); 
    1587                                                                 if (buffer[0] == 0x30) { 
    1588                                                                         manage_snmp (udp_poll.fd, (uint8_t *) buffer, rlen, &udp_client); 
    1589                                                                 } 
    1590                                                         } 
    1591                                                         else { 
    1592                                                                 perror ("inet_ntop()"); 
    1593                                                         } 
    1594                                                 } 
    1595                                         } 
    1596                                 } 
    1597                                 else { 
    1598                                         select (0, NULL, NULL, NULL, &check_interval); 
    1599                                 } 
    1600                                 working_workers = 0; 
    1601                                 blocking_workers = 0; 
    1602 #ifndef ROCK_SOLID 
    1603                                 if (uwsgi.has_threads && !uwsgi.i_have_gil) { 
    1604                                         PyEval_RestoreThread (uwsgi._save); 
    1605                                         uwsgi.i_have_gil = 1; 
    1606                                 } 
    1607 #endif 
    1608                                 check_interval.tv_sec = uwsgi.options[UWSGI_OPTION_MASTER_INTERVAL]; 
    1609                                 if (!check_interval.tv_sec) 
    1610                                         check_interval.tv_sec = 1; 
    1611                                 for (i = 1; i <= uwsgi.workers[0].current_workers; i++) { 
    1612                                         /* first check for harakiri */ 
    1613                                         if (uwsgi.workers[i].harakiri > 0) { 
    1614                                                 if (uwsgi.workers[i].harakiri < time (NULL)) { 
    1615                                                         /* first try to invoke the harakiri() custom handler */ 
    1616                                                         /* TODO */ 
    1617                                                         /* then brutally kill the worker */ 
    1618                                                         kill (uwsgi.workers[i].pid, SIGKILL); 
    1619                                                 } 
    1620                                         } 
    1621                                         /* load counters */ 
    1622                                         if (uwsgi.workers[i].in_request) 
    1623                                                 working_workers++; 
    1624  
    1625                                         if (uwsgi.workers[i].blocking) 
    1626                                                 blocking_workers++; 
    1627  
    1628                                         uwsgi.workers[i].last_running_time = uwsgi.workers[i].running_time; 
    1629                                 } 
    1630  
    1631                                 /* check if i need to add a subworker */ 
    1632                                 //fprintf(stderr,"working workers: %d\n",  working_workers); 
    1633                                 if (working_workers >= uwsgi.workers[0].current_workers) { 
    1634                                         /* ok the system is overloaded, check if some worker is in blocking mode */ 
    1635                                         if (blocking_workers > 0) { 
    1636                                                 /* check if is it safe to add a new worker (for now check only for enough free memory) */ 
    1637                                                 fprintf (stderr, "adding a new subworker as there are workers in blocking mode...\n"); 
    1638                                                 uwsgi.mywid = uwsgi.workers[0].current_workers + 1; 
    1639                                                 pid = fork (); 
    1640                                                 if (pid < 0) { 
    1641                                                         perror ("fork()"); 
    1642                                                 } 
    1643                                                 else if (pid > 0) { 
    1644                                                         fprintf (stderr, "spawned uWSGI subworker (pid: %d)\n", pid); 
    1645                                                         uwsgi.workers[uwsgi.workers[0].current_workers + 1].id = uwsgi.workers[0].current_workers + 1; 
    1646                                                         uwsgi.workers[uwsgi.workers[0].current_workers + 1].pid = pid; 
    1647                                                         uwsgi.workers[uwsgi.workers[0].current_workers + 1].harakiri = 0; 
    1648                                                         uwsgi.workers[uwsgi.workers[0].current_workers + 1].requests = 0; 
    1649                                                         uwsgi.workers[uwsgi.workers[0].current_workers + 1].failed_requests = 0; 
    1650                                                         uwsgi.workers[uwsgi.workers[0].current_workers + 1].respawn_count++; 
    1651                                                         uwsgi.workers[uwsgi.workers[0].current_workers + 1].last_spawn = time (NULL); 
    1652                                                         uwsgi.workers[uwsgi.workers[0].current_workers + 1].manage_next_request = 1; 
    1653                                                         uwsgi.workers[0].current_workers++; 
    1654                                                 } 
    1655                                                 else if (pid == 0) { 
    1656                                                         uwsgi.mypid = getpid (); 
    1657                                                         break; 
    1658                                                 } 
    1659                                         } 
    1660                                 } 
    1661                                 else { 
    1662                                         /* the system is no more overloaded, mark subworkers */ 
    1663                                         for (i = uwsgi.numproc + 1; i <= uwsgi.workers[0].current_workers; i++) { 
    1664                                                 uwsgi.workers[i].manage_next_request = 0; 
    1665                                         } 
    1666                                 } 
    1667  
    1668                                 /* now check for subworkers to remove */ 
    1669                                 for (i = uwsgi.workers[0].current_workers; i > uwsgi.numproc; i--) { 
    1670                                         if (uwsgi.workers[i].manage_next_request) 
    1671                                                 break; 
    1672                                         /* reset this worker (no interest in killing it) */ 
    1673                                         memset (&uwsgi.workers[i], 0, sizeof (struct uwsgi_worker)); 
    1674                                         uwsgi.workers[0].current_workers--; 
    1675                                 } 
    1676                                 continue; 
    1677                         } 
    1678 #ifndef ROCK_SOLID 
    1679 #ifndef PYTHREE 
    1680                         /* reload the spooler */ 
    1681                         if (spool_dir && uwsgi.workers[0].spooler_pid > 0) { 
    1682                                 if (diedpid == uwsgi.workers[0].spooler_pid) { 
    1683                                         fprintf(stderr,"OOOPS the spooler is no more...trying respawn...\n"); 
    1684                                         uwsgi.workers[0].spooler_pid = spooler_start (uwsgi.serverfd, uwsgi_module); 
    1685                                         continue; 
    1686                                 } 
    1687                         } 
    1688 #endif 
    1689 #endif 
    1690                         /* check for reloading */ 
    1691                         if (WIFEXITED (waitpid_status)) { 
    1692                                 if (WEXITSTATUS (waitpid_status) == UWSGI_RELOAD_CODE && uwsgi.to_heaven) { 
    1693                                         ready_to_reload++; 
    1694                                         continue; 
    1695                                 } 
    1696                                 else if (WEXITSTATUS (waitpid_status) == UWSGI_END_CODE && uwsgi.to_hell) { 
    1697                                         ready_to_die++; 
    1698                                         continue; 
    1699                                 } 
    1700                         } 
    1701  
    1702                         /* subworkers need to be respawned ? i do not think so */ 
    1703                         if (find_worker_id (diedpid) > uwsgi.numproc) { 
    1704                                 fprintf (stderr, "OOPS ! process %d (subworker id %d) died :( i will not respawn it.\n", diedpid, find_worker_id (diedpid)); 
    1705                                 /* decrease the number of workers */ 
    1706                                 if (uwsgi.workers[0].current_workers > uwsgi.numproc) { 
    1707                                         uwsgi.workers[find_worker_id (diedpid)].manage_next_request = 0; 
    1708                                 } 
    1709                                 continue; 
    1710                         } 
    1711                         fprintf (stderr, "DAMN ! process %d died :( trying respawn ...\n", diedpid); 
    1712                         gettimeofday (&last_respawn, NULL); 
    1713                         if (last_respawn.tv_sec == respawn_delta) { 
    1714                                 fprintf (stderr, "worker respawning too fast !!! i have to sleep a bit...\n"); 
    1715                                 /* TODO, user configurable fork throttler */ 
    1716                                 sleep (2); 
    1717                         } 
    1718                         gettimeofday (&last_respawn, NULL); 
    1719                         respawn_delta = last_respawn.tv_sec; 
    1720                         uwsgi.mywid = find_worker_id (diedpid); 
    1721                         pid = fork (); 
    1722                         if (pid == 0) { 
    1723                                 uwsgi.mypid = getpid ();