/[jscoverage]/trunk/jscoverage-server.c
ViewVC logotype

Diff of /trunk/jscoverage-server.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 119 by siliconforks, Sun Jun 1 14:05:47 2008 UTC revision 133 by siliconforks, Thu Jun 19 05:53:29 2008 UTC
# Line 25  Line 25 
25  #include <string.h>  #include <string.h>
26    
27  #include <dirent.h>  #include <dirent.h>
28    #ifdef HAVE_PTHREAD_H
29  #include <pthread.h>  #include <pthread.h>
30    #endif
31    
32  #include "http-server.h"  #include "http-server.h"
33  #include "instrument-js.h"  #include "instrument-js.h"
# Line 64  Line 66 
66  static const char ** no_instrument;  static const char ** no_instrument;
67  static size_t num_no_instrument = 0;  static size_t num_no_instrument = 0;
68    
69    #ifdef __MINGW32__
70    CRITICAL_SECTION javascript_mutex;
71    CRITICAL_SECTION source_cache_mutex;
72    #define LOCK EnterCriticalSection
73    #define UNLOCK LeaveCriticalSection
74    #else
75  pthread_mutex_t javascript_mutex = PTHREAD_MUTEX_INITIALIZER;  pthread_mutex_t javascript_mutex = PTHREAD_MUTEX_INITIALIZER;
76  pthread_mutex_t source_cache_mutex = PTHREAD_MUTEX_INITIALIZER;  pthread_mutex_t source_cache_mutex = PTHREAD_MUTEX_INITIALIZER;
77    #define LOCK pthread_mutex_lock
78    #define UNLOCK pthread_mutex_unlock
79    #endif
80    
81  static Stream * find_cached_source(const char * url) {  static Stream * find_cached_source(const char * url) {
82    Stream * result = NULL;    Stream * result = NULL;
83    pthread_mutex_lock(&source_cache_mutex);    LOCK(&source_cache_mutex);
84    for (SourceCache * p = source_cache; p != NULL; p = p->next) {    for (SourceCache * p = source_cache; p != NULL; p = p->next) {
85      if (strcmp(url, p->url) == 0) {      if (strcmp(url, p->url) == 0) {
86        result = p->source;        result = p->source;
87        break;        break;
88      }      }
89    }    }
90    pthread_mutex_unlock(&source_cache_mutex);    UNLOCK(&source_cache_mutex);
91    return result;    return result;
92  }  }
93    
# Line 84  Line 95 
95    SourceCache * new_source_cache = xmalloc(sizeof(SourceCache));    SourceCache * new_source_cache = xmalloc(sizeof(SourceCache));
96    new_source_cache->url = xstrdup(url);    new_source_cache->url = xstrdup(url);
97    new_source_cache->source = source;    new_source_cache->source = source;
98    pthread_mutex_lock(&source_cache_mutex);    LOCK(&source_cache_mutex);
99    new_source_cache->next = source_cache;    new_source_cache->next = source_cache;
100    source_cache = new_source_cache;    source_cache = new_source_cache;
101    pthread_mutex_unlock(&source_cache_mutex);    UNLOCK(&source_cache_mutex);
102  }  }
103    
104  static int get(const char * url, Stream * stream) __attribute__((warn_unused_result));  static int get(const char * url, Stream * stream) __attribute__((warn_unused_result));
# Line 344  Line 355 
355    Stream * stream = Stream_new(0);    Stream * stream = Stream_new(0);
356    Stream_write_file_contents(stream, f);    Stream_write_file_contents(stream, f);
357    
358    pthread_mutex_lock(&javascript_mutex);    LOCK(&javascript_mutex);
359    int result = jscoverage_parse_json(coverage, stream->data, stream->length);    int result = jscoverage_parse_json(coverage, stream->data, stream->length);
360    pthread_mutex_unlock(&javascript_mutex);    UNLOCK(&javascript_mutex);
361    
362    Stream_delete(stream);    Stream_delete(stream);
363    return result;    return result;
# Line 435  Line 446 
446        /* check that the path begins with / */        /* check that the path begins with / */
447        if (file_coverage->id[0] == '/') {        if (file_coverage->id[0] == '/') {
448          char * source_path = make_path(document_root, file_coverage->id + 1);          char * source_path = make_path(document_root, file_coverage->id + 1);
449          FILE * source_file = fopen(source_path, "r");          FILE * source_file = fopen(source_path, "rb");
450          free(source_path);          free(source_path);
451          if (source_file == NULL) {          if (source_file == NULL) {
452            fputs("\"\"", f);            fputs("\"\"", f);
# Line 502  Line 513 
513      }      }
514    
515      Coverage * coverage = Coverage_new();      Coverage * coverage = Coverage_new();
516      pthread_mutex_lock(&javascript_mutex);      LOCK(&javascript_mutex);
517      int result = jscoverage_parse_json(coverage, json->data, json->length);      int result = jscoverage_parse_json(coverage, json->data, json->length);
518      pthread_mutex_unlock(&javascript_mutex);      UNLOCK(&javascript_mutex);
519      Stream_delete(json);      Stream_delete(json);
520    
521      if (result != 0) {      if (result != 0) {
# Line 515  Line 526 
526    
527      mkdir_if_necessary(report_directory);      mkdir_if_necessary(report_directory);
528      char * path = make_path(report_directory, "jscoverage.json");      char * path = make_path(report_directory, "jscoverage.json");
529      FILE * f = fopen(path, "r");  
530      if (f != NULL) {      /* check if the JSON file exists */
531        struct stat buf;
532        if (stat(path, &buf) == 0) {
533        /* it exists: merge */        /* it exists: merge */
534        result = merge(coverage, f);        FILE * f = fopen(path, "r");
535        if (fclose(f) == EOF) {        if (f == NULL) {
536          result = 1;          result = 1;
537        }        }
538          else {
539            result = merge(coverage, f);
540            if (fclose(f) == EOF) {
541              result = 1;
542            }
543          }
544        if (result != 0) {        if (result != 0) {
545          free(path);          free(path);
546          Coverage_delete(coverage);          Coverage_delete(coverage);
# Line 541  Line 560 
560      /* copy other files */      /* copy other files */
561      jscoverage_copy_resources(report_directory);      jscoverage_copy_resources(report_directory);
562      path = make_path(report_directory, "jscoverage.js");      path = make_path(report_directory, "jscoverage.js");
563      f = fopen(path, "ab");      FILE * f = fopen(path, "ab");
564      free(path);      free(path);
565      if (f == NULL) {      if (f == NULL) {
566        send_response(exchange, 500, "Could not write to file: jscoverage.js\n");        send_response(exchange, 500, "Could not write to file: jscoverage.js\n");
# Line 598  Line 617 
617  }  }
618    
619  static void instrument_js(const char * id, Stream * input_stream, Stream * output_stream) {  static void instrument_js(const char * id, Stream * input_stream, Stream * output_stream) {
620    pthread_mutex_lock(&javascript_mutex);    LOCK(&javascript_mutex);
621    jscoverage_instrument_js(id, input_stream, output_stream);    jscoverage_instrument_js(id, input_stream, output_stream);
622    pthread_mutex_unlock(&javascript_mutex);    UNLOCK(&javascript_mutex);
623    
624    const struct Resource * resource = get_resource("report.js");    const struct Resource * resource = get_resource("report.js");
625    Stream_write(output_stream, resource->data, resource->length);    Stream_write(output_stream, resource->data, resource->length);
# Line 808  Line 827 
827    }    }
828    
829    filesystem_path = make_path(document_root, abs_path + 1);    filesystem_path = make_path(document_root, abs_path + 1);
830      size_t filesystem_path_length = strlen(filesystem_path);
831      if (filesystem_path_length > 0 && filesystem_path[filesystem_path_length - 1] == '/') {
832        /* stat on Windows doesn't work with trailing slash */
833        filesystem_path[filesystem_path_length - 1] = '\0';
834      }
835    
836    struct stat buf;    struct stat buf;
837    if (stat(filesystem_path, &buf) == -1) {    if (stat(filesystem_path, &buf) == -1) {
# Line 816  Line 840 
840    }    }
841    
842    if (S_ISDIR(buf.st_mode)) {    if (S_ISDIR(buf.st_mode)) {
843      if (filesystem_path[strlen(filesystem_path) - 1] != '/') {      if (abs_path[strlen(abs_path) - 1] != '/') {
844        const char * request_uri = HTTPExchange_get_request_uri(exchange);        const char * request_uri = HTTPExchange_get_request_uri(exchange);
845        char * uri = xmalloc(strlen(request_uri) + 2);        char * uri = xmalloc(strlen(request_uri) + 2);
846        strcpy(uri, request_uri);        strcpy(uri, request_uri);
# Line 851  Line 875 
875      closedir(d);      closedir(d);
876    }    }
877    else if (S_ISREG(buf.st_mode)) {    else if (S_ISREG(buf.st_mode)) {
878      FILE * f = fopen(filesystem_path, "r");      FILE * f = fopen(filesystem_path, "rb");
879      if (f == NULL) {      if (f == NULL) {
880        send_response(exchange, 404, "Not found\n");        send_response(exchange, 404, "Not found\n");
881        goto done;        goto done;
# Line 1015  Line 1039 
1039    
1040    /* is this a shutdown? */    /* is this a shutdown? */
1041    if (shutdown) {    if (shutdown) {
1042    #ifdef __MINGW32__
1043        WSADATA data;
1044        if (WSAStartup(MAKEWORD(1, 1), &data) != 0) {
1045          fatal("Could not start Winsock");
1046        }
1047    #endif
1048    
1049      /* INADDR_LOOPBACK */      /* INADDR_LOOPBACK */
1050      HTTPConnection * connection = HTTPConnection_new_client("127.0.0.1", numeric_port);      HTTPConnection * connection = HTTPConnection_new_client("127.0.0.1", numeric_port);
1051      if (connection == NULL) {      if (connection == NULL) {
# Line 1044  Line 1075 
1075    
1076    jscoverage_init();    jscoverage_init();
1077    
1078    #ifndef __MINGW32__
1079    /* handle broken pipe */    /* handle broken pipe */
1080    signal(SIGPIPE, SIG_IGN);    signal(SIGPIPE, SIG_IGN);
1081    #endif
1082    
1083    #ifdef __MINGW32__
1084    InitializeCriticalSection(&javascript_mutex);
1085    InitializeCriticalSection(&source_cache_mutex);
1086    #endif
1087    
1088    if (verbose) {    if (verbose) {
1089      printf("Starting HTTP server on %s:%lu\n", ip_address, numeric_port);      printf("Starting HTTP server on %s:%lu\n", ip_address, numeric_port);
1090        fflush(stdout);
1091    }    }
1092    HTTPServer_run(ip_address, (uint16_t) numeric_port, handler);    HTTPServer_run(ip_address, (uint16_t) numeric_port, handler);
1093    if (verbose) {    if (verbose) {
1094      printf("Stopping HTTP server\n");      printf("Stopping HTTP server\n");
1095        fflush(stdout);
1096    }    }
1097    
1098    jscoverage_cleanup();    jscoverage_cleanup();
1099    
1100    free(no_instrument);    free(no_instrument);
1101    
1102    pthread_mutex_lock(&source_cache_mutex);    LOCK(&source_cache_mutex);
1103    while (source_cache != NULL) {    while (source_cache != NULL) {
1104      SourceCache * p = source_cache;      SourceCache * p = source_cache;
1105      source_cache = source_cache->next;      source_cache = source_cache->next;
# Line 1067  Line 1107 
1107      Stream_delete(p->source);      Stream_delete(p->source);
1108      free(p);      free(p);
1109    }    }
1110    pthread_mutex_unlock(&source_cache_mutex);    UNLOCK(&source_cache_mutex);
1111    
1112    return 0;    return 0;
1113  }  }

Legend:
Removed from v.119  
changed lines
  Added in v.133

  ViewVC Help
Powered by ViewVC 1.1.24