static vthread *alloc_thread( neko_vm *vm ) { vthread *t = (vthread*)alloc(sizeof(vthread)); memset(t,0,sizeof(vthread)); #ifdef NEKO_WINDOWS t->tid = GetCurrentThreadId(); #else t->phandle = pthread_self(); #endif t->v = alloc_abstract(k_thread,t); t->vm = vm; _deque_init(&t->q); val_gc(t->v,free_thread); return t; }
static value cert_load_path(value path){ int r; mbedtls_x509_crt *x; value v; val_check(path,string); x = (mbedtls_x509_crt *)alloc(sizeof(mbedtls_x509_crt)); mbedtls_x509_crt_init( x ); if( (r = mbedtls_x509_crt_parse_path(x, val_string(path))) != 0 ){ return ssl_error(r); } v = alloc_abstract(k_cert, x); val_gc(v,free_cert); return v; }
/** Create a client side ENetHost with 'connections' max outgoing connections using the specified bandwidth limits. **/ static value udpr_client_create(value connections, value incoming, value outgoing) { ENetHost *h; h = enet_host_create( NULL, (size_t)val_int(connections), /* number of clients and/or outgoing connections */ (enet_uint32)val_int32(incoming), /* amount of incoming bandwidth in Bytes/sec */ (enet_uint32)val_int32(outgoing)); if(h == NULL) //val_throw(alloc_string("Host creation failure")); neko_error(); value v = alloc_abstract(k_udprhost,h); val_gc(v, destroy_enethost); return v; }
/** connect : filename:string -> 'db <doc>Open or create the database stored in the specified file.</doc> **/ static value connect( value filename ) { int err; database *db = (database*)alloc(sizeof(database)); value v; val_check(filename,string); db->last = NULL; if( (err = sqlite3_open(val_string(filename),&db->db)) != SQLITE_OK ) { buffer b = alloc_buffer("Sqlite error : "); buffer_append(b,sqlite3_errmsg(db->db)); sqlite3_close(db->db); val_throw(buffer_to_string(b)); } v = alloc_abstract(k_db,db); val_gc(v,free_db); return v; }
/** deflate_init : level:int -> 'dstream <doc>Open a compression stream with the given level of compression</doc> **/ static value deflate_init( value level ) { z_stream *z; value s; int err; val_check(level,int); z = (z_stream*)malloc(sizeof(z_stream) + sizeof(int)); memset(z,0,sizeof(z_stream)); val_flush(z) = Z_NO_FLUSH; if( (err = deflateInit(z,val_int(level))) != Z_OK ) { free(z); zlib_error(NULL,err); } s = alloc_abstract(k_stream_def,z); val_gc(s,free_stream_def); return s; }
value lime_text_layout_create (value direction, value script, value language) { #if defined(LIME_FREETYPE) && defined(LIME_HARFBUZZ) TextLayout *text = new TextLayout (val_int (direction), val_string (script), val_string (language)); value v = alloc_float ((intptr_t)text); val_gc (v, lime_text_layout_destroy); return v; #else return alloc_null (); #endif }
/** lock_create : void -> 'lock <doc>Creates a lock which is initially locked</doc> **/ static value lock_create() { value vl; vlock l; # ifdef NEKO_WINDOWS l = CreateSemaphore(NULL,0,(1 << 30),NULL); if( l == NULL ) neko_error(); # else l = (vlock)alloc_private(sizeof(struct _vlock)); l->counter = 0; if( pthread_mutex_init(&l->lock,NULL) != 0 || pthread_cond_init(&l->cond,NULL) != 0 ) neko_error(); # endif vl = alloc_abstract(k_lock,l); val_gc(vl,free_lock); return vl; }
/** file_open : f:string -> r:string -> 'file <doc> Call the C function [fopen] with the file path and access rights. Return the opened file or throw an exception if the file couldn't be open. </doc> **/ static value file_open( value name, value r ) { val_check(name,string); val_check(r,string); fio *f = new fio(val_filename(name)); const char *fname = val_string(name); const char *mode = val_string(r); gc_enter_blocking(); f->io = fopen(fname,mode); if( f->io == NULL ) { file_error("file_open",f,true); } gc_exit_blocking(); value result = alloc_abstract(k_file,f); val_gc(result,free_file); return result; }
/** tmpfile_open : <doc> Calls tmpfile to create a temporary file </doc> **/ static value tmpfile_open() { fio * f; vkind k_file = kind_import("file"); if(k_file == NULL) tmpfile_error("tmpfile_open k_file"); f = (fio*)alloc(sizeof(fio)); f->name = alloc_string("tmpfile"); f->io = tmpfile(); //f->io = fopen("/tmp/myfile","w+"); if( f->io == NULL ) tmpfile_error("tmpfile_open"); value v = alloc_abstract(k_file,f); val_gc(v, cleanup); return v; }
value ftLoadFont( value _data, value _width, value _height ) { val_check(_data,string); val_check(_width,number); val_check(_height,number); int width = val_number(_width); int height = val_number(_height); value font = alloc_object(NULL); FT_Face *face = (FT_Face*)malloc( sizeof(FT_Face) ); if( !face ) val_throw( alloc_string("out of memory") ); int err = FT_New_Memory_Face( ft_library, (const FT_Byte*)val_string(_data), val_strlen(_data), 0, face ); if( err == FT_Err_Unknown_File_Format ) val_throw( alloc_string("Freetype cant read font (unknown format)")); else if( err ) val_throw( alloc_string("Freetype cant read font")); FT_Set_Char_Size( *face, width, height, 72, 72 ); int n_glyphs = (*face)->num_glyphs; // set some global metrics/info alloc_field( font, val_id("family_name"), alloc_string((*face)->family_name) ); alloc_field( font, val_id("style_name"), alloc_string((*face)->style_name) ); alloc_field( font, val_id("ascender"), alloc_int((*face)->ascender) ); alloc_field( font, val_id("descender"), alloc_int((*face)->descender) ); alloc_field( font, val_id("units_per_EM"), alloc_int((*face)->units_per_EM) ); alloc_field( font, val_id("height"), alloc_int((*face)->height) ); alloc_field( font, val_id("max_advance_width"), alloc_int((*face)->max_advance_width) ); alloc_field( font, val_id("max_advance_height"), alloc_int((*face)->max_advance_height) ); alloc_field( font, val_id("underline_position"), alloc_int((*face)->underline_position) ); alloc_field( font, val_id("underline_thickness"), alloc_int((*face)->underline_thickness) ); value __f = alloc_abstract( k_ft_face, face ); val_gc( __f, _font_finalize ); alloc_field( font, val_id("__f"), __f ); //fprintf(stderr,"Load Font %p\n", face ); return font; }
static value cert_add_der( value cert, value data ){ mbedtls_x509_crt *crt; int r; val_check(data,string); if( !val_is_null(cert) ){ val_check_kind(cert,k_cert); crt = val_cert(cert); if( !crt ) neko_error(); }else{ crt = (mbedtls_x509_crt *)alloc(sizeof(mbedtls_x509_crt)); mbedtls_x509_crt_init( crt ); cert = alloc_abstract(k_cert, crt); val_gc(cert,free_cert); } if( (r = mbedtls_x509_crt_parse_der(crt, (const unsigned char*)val_string(data), val_strlen(data))) < 0 ) return ssl_error(r); return cert; }
static value key_from_der( value data, value pub ){ mbedtls_pk_context *pk; int r; value v; val_check(data, string); val_check(pub, bool); pk = (mbedtls_pk_context *)alloc(sizeof(mbedtls_pk_context)); mbedtls_pk_init(pk); if( val_bool(pub) ) r = mbedtls_pk_parse_public_key( pk, (const unsigned char*)val_string(data), val_strlen(data) ); else r = mbedtls_pk_parse_key( pk, (const unsigned char*)val_string(data), val_strlen(data), NULL, 0 ); if( r != 0 ){ mbedtls_pk_free(pk); return ssl_error(r); } v = alloc_abstract(k_pkey, pk); val_gc(v,free_pkey); return v; }
value CFFIPointer (void* ptr, hx::finalizer finalizer) { if (ptr) { value handle = cffi::alloc_pointer (ptr); if (finalizer) { val_gc (handle, finalizer); } return handle; } else { return alloc_null (); } }
static value alloc_result( connection *c, MYSQL_RES *r ) { result *res = (result*)alloc(sizeof(result)); value o = alloc_abstract(k_result,res); int num_fields = mysql_num_fields(r); int i,j; MYSQL_FIELD *fields = mysql_fetch_fields(r); res->r = r; res->conv_date = c->conv_date; res->conv_bytes = c->conv_bytes; res->conv_string = c->conv_string; res->current = NULL; res->nfields = num_fields; res->fields_ids = (field*)alloc_private(sizeof(field)*num_fields); res->fields_convs = (CONV*)alloc_private(sizeof(CONV)*num_fields); for(i=0;i<num_fields;i++) { field id; if( strchr(fields[i].name,'(') ) id = val_id("???"); // looks like an inner request : prevent hashing + cashing it else { id = val_id(fields[i].name); for(j=0;j<i;j++) if( res->fields_ids[j] == id ) { buffer b = alloc_buffer("Error, same field ids for : "); buffer_append(b,fields[i].name); buffer_append(b,":"); val_buffer(b,alloc_int(i)); buffer_append(b," and "); buffer_append(b,fields[j].name); buffer_append(b,":"); val_buffer(b,alloc_int(j)); buffer_append(b,"."); bfailure(b); } } res->fields_ids[i] = id; res->fields_convs[i] = convert_type(fields[i].type,fields[i].flags,fields[i].length); } val_gc(o,free_result); return o; }
/** socket_bind : host : int32 -> port:int -> connections:int -> incoming:int32 -> outgoing:int32 -> bool <doc>Bind a UDPR socket for server usage on the given host and port, with max connections, incoming bandwidth limited to bytes per second or 0 for unlimited, outgoing also. Host may be val_type_null, in which case the binding is to ENET_HOST_ANY </doc> **/ static value udpr_bind( value ip, value port, value connections, value incoming, value outgoing ) { ENetAddress address; ENetHost *s; val_check(connections,int); val_check(incoming,int32); val_check(outgoing,int32); if(populate_address(& address, ip, port) != val_true) neko_error(); s = enet_host_create( &address, (size_t)val_int(connections), /* number of clients and/or outgoing connections */ (enet_uint32)val_int32(incoming), /* amount of incoming bandwidth in Bytes/sec */ (enet_uint32)val_int32(outgoing)); if(s == NULL) neko_error(); value v = alloc_abstract(k_udprhost,s); val_gc(v, destroy_enethost); #ifdef ENET_DEBUG fprintf(stderr, "udpr_bind: complete\n"); #endif return v; }
value hx_zmq_construct_socket (value context_handle,value type) { val_is_kind(context_handle,k_zmq_context_handle); if (!val_is_int(type)) { val_throw(alloc_int(EINVAL)); return alloc_null(); } void *s = zmq_socket (val_data(context_handle),val_int(type)); int err = zmq_errno(); if (s == NULL) { val_throw (alloc_int(err)); return alloc_null(); } // See: http://nekovm.org/doc/ffi#abstracts_and_kinds value v = alloc_abstract(k_zmq_socket_handle,s); val_gc(v,finalize_socket); // finalize_socket is called when the abstract value is garbage collected return v; }
/** inflate_init : window_size:int? -> 'istream <doc>Open a decompression stream</doc> **/ static value inflate_init( value wsize ) { z_stream *z; value s; int err; int wbits; if( val_is_null(wsize) ) wbits = MAX_WBITS; else { val_check(wsize,int); wbits = val_int(wsize); } z = (z_stream*)malloc(sizeof(z_stream) + sizeof(int)); memset(z,0,sizeof(z_stream)); val_flush(z) = Z_NO_FLUSH; if( (err = inflateInit2(z,wbits)) != Z_OK ) { free(z); zlib_error(NULL,err); } s = alloc_abstract(k_stream_inf,z); val_gc(s,free_stream_inf); return s; }
value lime_font_load (value data) { #ifdef LIME_FREETYPE Resource resource; if (val_is_string (data)) { resource = Resource (val_string (data)); } else { Bytes bytes (data); resource = Resource (&bytes); } Font *font = new Font (&resource, 0); if (font) { if (font->face) { value v = alloc_float ((intptr_t)font); val_gc (v, lime_font_destroy); return v; } else { delete font; } } #endif return alloc_null (); }
/** Free an allocated ENetEvent struct from neko **/ static value free_enetevent( value e ) { val_check_kind(e,k_udprevent); ENetEvent *event = (ENetEvent *)val_data(e); if(e == NULL) neko_error(); // enet_packet_destroy frees the packet itself. #ifdef ENET_DEBUG printf("*** free_enetevent freeing packet\n"); #endif if(event->packet != NULL) enet_packet_destroy (event->packet); #ifdef ENET_DEBUG //printf("*** free_enetevent freeing event\n"); #endif enet_free(event); val_gc(e,NULL); val_kind(e) = NULL; #ifdef ENET_DEBUG //printf("*** free_enetevent done.\n"); #endif return val_true; }
static value cert_add_pem( value cert, value data ){ mbedtls_x509_crt *crt; int r, len; unsigned char *buf; val_check(data,string); if( !val_is_null(cert) ){ val_check_kind(cert,k_cert); crt = val_cert(cert); if( !crt ) neko_error(); }else{ crt = (mbedtls_x509_crt *)alloc(sizeof(mbedtls_x509_crt)); mbedtls_x509_crt_init( crt ); cert = alloc_abstract(k_cert, crt); val_gc(cert,free_cert); } len = val_strlen(data)+1; buf = (unsigned char *)alloc(len); memcpy(buf, val_string(data), len-1); buf[len-1] = '\0'; if( (r = mbedtls_x509_crt_parse(crt, buf, len)) < 0 ) return ssl_error(r); return cert; }
/** process_close : 'process -> void <doc> Close the process I/O. </doc> **/ static value process_close( value vp ) { val_check_kind(vp,k_process); free_process(vp); val_gc(vp,NULL); return val_null; }
/** process_run : cmd:string -> args:string array -> 'process <doc> Start a process using a command and the specified arguments. When args is not null, cmd and args will be auto-quoted/escaped. If no auto-quoting/escaping is desired, you should append necessary arguments to cmd as if it is inputted to the shell directly, and pass null as args. </doc> **/ static value process_run( value cmd, value vargs ) { int i, isRaw; vprocess *p; val_check(cmd,string); isRaw = val_is_null(vargs); if (!isRaw) { val_check(vargs,array); } # ifdef NEKO_WINDOWS { SECURITY_ATTRIBUTES sattr; STARTUPINFO sinf; HANDLE proc = GetCurrentProcess(); HANDLE oread,eread,iwrite; // creates commandline buffer b = alloc_buffer(NULL); value sargs; if (isRaw) { char* cmdexe = getenv("COMSPEC"); if (!cmdexe) cmdexe = "cmd.exe"; buffer_append(b,"\""); buffer_append(b,cmdexe); buffer_append(b,"\" /C \""); buffer_append(b,val_string(cmd)); buffer_append_char(b,'"'); } else { buffer_append_char(b,'"'); val_buffer(b,cmd); buffer_append_char(b,'"'); for(i=0;i<val_array_size(vargs);i++) { value v = val_array_ptr(vargs)[i]; int j,len; unsigned int bs_count = 0; unsigned int k; val_check(v,string); len = val_strlen(v); buffer_append(b," \""); for(j=0;j<len;j++) { char c = val_string(v)[j]; switch( c ) { case '"': // Double backslashes. for (k=0;k<bs_count*2;k++) { buffer_append_char(b,'\\'); } bs_count = 0; buffer_append(b, "\\\""); break; case '\\': // Don't know if we need to double yet. bs_count++; break; default: // Normal char for (k=0;k<bs_count;k++) { buffer_append_char(b,'\\'); } bs_count = 0; buffer_append_char(b,c); break; } } // Add remaining backslashes, if any. for (k=0;k<bs_count*2;k++) { buffer_append_char(b,'\\'); } buffer_append_char(b,'"'); } } sargs = buffer_to_string(b); p = (vprocess*)alloc_private(sizeof(vprocess)); // startup process sattr.nLength = sizeof(sattr); sattr.bInheritHandle = TRUE; sattr.lpSecurityDescriptor = NULL; memset(&sinf,0,sizeof(sinf)); sinf.cb = sizeof(sinf); sinf.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; sinf.wShowWindow = SW_HIDE; CreatePipe(&oread,&sinf.hStdOutput,&sattr,0); CreatePipe(&eread,&sinf.hStdError,&sattr,0); CreatePipe(&sinf.hStdInput,&iwrite,&sattr,0); DuplicateHandle(proc,oread,proc,&p->oread,0,FALSE,DUPLICATE_SAME_ACCESS); DuplicateHandle(proc,eread,proc,&p->eread,0,FALSE,DUPLICATE_SAME_ACCESS); DuplicateHandle(proc,iwrite,proc,&p->iwrite,0,FALSE,DUPLICATE_SAME_ACCESS); CloseHandle(oread); CloseHandle(eread); CloseHandle(iwrite); if( !CreateProcess(NULL,val_string(sargs),NULL,NULL,TRUE,0,NULL,NULL,&sinf,&p->pinf) ) neko_error(); // close unused pipes CloseHandle(sinf.hStdOutput); CloseHandle(sinf.hStdError); CloseHandle(sinf.hStdInput); } # else char **argv; if (isRaw) { argv = (char**)alloc_private(sizeof(char*)*4); argv[0] = "/bin/sh"; argv[1] = "-c"; argv[2] = val_string(cmd); argv[3] = NULL; } else { argv = (char**)alloc_private(sizeof(char*)*(val_array_size(vargs)+2)); argv[0] = val_string(cmd); for(i=0;i<val_array_size(vargs);i++) { value v = val_array_ptr(vargs)[i]; val_check(v,string); argv[i+1] = val_string(v); } argv[i+1] = NULL; } int input[2], output[2], error[2]; if( pipe(input) || pipe(output) || pipe(error) ) neko_error(); p = (vprocess*)alloc_private(sizeof(vprocess)); p->pid = fork(); if( p->pid == -1 ) { do_close(input[0]); do_close(input[1]); do_close(output[0]); do_close(output[1]); do_close(error[0]); do_close(error[1]); neko_error(); } // child if( p->pid == 0 ) { close(input[1]); close(output[0]); close(error[0]); dup2(input[0],0); dup2(output[1],1); dup2(error[1],2); execvp(argv[0],argv); fprintf(stderr,"Command not found : %s\n",val_string(cmd)); exit(1); } // parent do_close(input[0]); do_close(output[1]); do_close(error[1]); p->iwrite = input[1]; p->oread = output[0]; p->eread = error[0]; # endif { value vp = alloc_abstract(k_process,p); val_gc(vp,free_process); return vp; } }
/** process_run : cmd:string -> args:string array -> 'process <doc> Start a process using a command and the specified arguments. </doc> **/ CAMLprim value process_run( value cmd, value vargs ) { int i; vprocess *p; val_check(cmd,string); val_check(vargs,array); # ifdef _WIN32 { SECURITY_ATTRIBUTES sattr; STARTUPINFO sinf; HANDLE proc = GetCurrentProcess(); HANDLE oread,eread,iwrite; // creates commandline buffer b = alloc_buffer(NULL); char *sargs; buffer_append_char(b,'"'); buffer_append_str(b,val_string(cmd)); buffer_append_char(b,'"'); for(i=0;i<val_array_size(vargs);i++) { value v = val_array_ptr(vargs)[i]; int j,len; val_check(v,string); len = val_strlen(v); buffer_append_str(b," \""); for(j=0;j<len;j++) { char c = val_string(v)[j]; switch( c ) { case '"': buffer_append_str(b,"\\\""); break; case '\\': buffer_append_str(b,"\\\\"); break; default: buffer_append_char(b,c); break; } } buffer_append_char(b,'"'); } sargs = buffer_to_string(b); p = (vprocess*)alloc_private(sizeof(vprocess)); // startup process sattr.nLength = sizeof(sattr); sattr.bInheritHandle = TRUE; sattr.lpSecurityDescriptor = NULL; memset(&sinf,0,sizeof(sinf)); sinf.cb = sizeof(sinf); sinf.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; sinf.wShowWindow = SW_HIDE; CreatePipe(&oread,&sinf.hStdOutput,&sattr,0); CreatePipe(&eread,&sinf.hStdError,&sattr,0); CreatePipe(&sinf.hStdInput,&iwrite,&sattr,0); DuplicateHandle(proc,oread,proc,&p->oread,0,FALSE,DUPLICATE_SAME_ACCESS); DuplicateHandle(proc,eread,proc,&p->eread,0,FALSE,DUPLICATE_SAME_ACCESS); DuplicateHandle(proc,iwrite,proc,&p->iwrite,0,FALSE,DUPLICATE_SAME_ACCESS); CloseHandle(oread); CloseHandle(eread); CloseHandle(iwrite); if( !CreateProcess(NULL,val_string(sargs),NULL,NULL,TRUE,0,NULL,NULL,&sinf,&p->pinf) ) { CloseHandle(p->eread); CloseHandle(p->oread); CloseHandle(p->iwrite); free(sargs); neko_error(); } free(sargs); // close unused pipes CloseHandle(sinf.hStdOutput); CloseHandle(sinf.hStdError); CloseHandle(sinf.hStdInput); } # else char **argv = (char**)alloc_private(sizeof(char*)*(val_array_size(vargs)+2)); argv[0] = val_string(cmd); for(i=0;i<val_array_size(vargs);i++) { value v = val_array_ptr(vargs)[i]; val_check(v,string); argv[i+1] = val_string(v); } argv[i+1] = NULL; int input[2], output[2], error[2]; if( pipe(input) || pipe(output) || pipe(error) ) neko_error(); p = (vprocess*)alloc_private(sizeof(vprocess)); p->pid = fork(); if( p->pid == -1 ) { do_close(input[0]); do_close(input[1]); do_close(output[0]); do_close(output[1]); do_close(error[0]); do_close(error[1]); neko_error(); } // child if( p->pid == 0 ) { close(input[1]); close(output[0]); close(error[0]); dup2(input[0],0); dup2(output[1],1); dup2(error[1],2); execvp(val_string(cmd),argv); fprintf(stderr,"Command not found : %s\n",val_string(cmd)); exit(1); } // parent do_close(input[0]); do_close(output[1]); do_close(error[1]); p->iwrite = input[1]; p->oread = output[0]; p->eread = error[0]; # endif { value vp = alloc_abstract(k_process,p); val_gc(vp,free_process); return vp; } }
static value cert_load_defaults(){ #if defined(NEKO_WINDOWS) value v; HCERTSTORE store; PCCERT_CONTEXT cert; mbedtls_x509_crt *chain = (mbedtls_x509_crt *)alloc(sizeof(mbedtls_x509_crt)); mbedtls_x509_crt_init( chain ); if( store = CertOpenSystemStore(0, (LPCSTR)"Root") ){ cert = NULL; while( cert = CertEnumCertificatesInStore(store, cert) ) mbedtls_x509_crt_parse_der( chain, (unsigned char *)cert->pbCertEncoded, cert->cbCertEncoded ); CertCloseStore(store, 0); } v = alloc_abstract(k_cert, chain); val_gc(v,free_cert); return v; #elif defined(NEKO_MAC) CFMutableDictionaryRef search; CFArrayRef result; SecKeychainRef keychain; SecCertificateRef item; CFDataRef dat; value v; mbedtls_x509_crt *chain = NULL; // Load keychain if( SecKeychainOpen("/System/Library/Keychains/SystemRootCertificates.keychain",&keychain) != errSecSuccess ) return val_null; // Search for certificates search = CFDictionaryCreateMutable( NULL, 0, NULL, NULL ); CFDictionarySetValue( search, kSecClass, kSecClassCertificate ); CFDictionarySetValue( search, kSecMatchLimit, kSecMatchLimitAll ); CFDictionarySetValue( search, kSecReturnRef, kCFBooleanTrue ); CFDictionarySetValue( search, kSecMatchSearchList, CFArrayCreate(NULL, (const void **)&keychain, 1, NULL) ); if( SecItemCopyMatching( search, (CFTypeRef *)&result ) == errSecSuccess ){ CFIndex n = CFArrayGetCount( result ); for( CFIndex i = 0; i < n; i++ ){ item = (SecCertificateRef)CFArrayGetValueAtIndex( result, i ); // Get certificate in DER format dat = SecCertificateCopyData( item ); if( dat ){ if( chain == NULL ){ chain = (mbedtls_x509_crt *)alloc(sizeof(mbedtls_x509_crt)); mbedtls_x509_crt_init( chain ); } mbedtls_x509_crt_parse_der( chain, (unsigned char *)CFDataGetBytePtr(dat), CFDataGetLength(dat) ); CFRelease( dat ); } } } CFRelease(keychain); if( chain != NULL ){ v = alloc_abstract(k_cert, chain); val_gc(v,free_cert); return v; }else{ return val_null; } #else return val_null; #endif }
value _ofxOscReceiver_new() { value ret = alloc_abstract(_ofxOscReceiver, new ofxOscReceiver()); val_gc(ret, delete_ofxOscReceiver); return ret; }
value _ofxOscMessage_new() { value ret = alloc_abstract(_ofxOscMessage, new ofxOscMessage()); val_gc(ret, delete_ofxOscMessage); return ret; }
value _ofxOscBundle_new() { value ret = alloc_abstract(_ofxOscBundle, new ofxOscBundle()); val_gc(ret, delete_ofxOscBundle); return ret; }
/** process_run : cmd:string -> args:string array -> 'process <doc> Start a process using a command and the specified arguments. </doc> **/ static value process_run( value cmd, value vargs ) { int i; vprocess *p; val_check(cmd,string); val_check(vargs,array); # ifdef NEKO_WINDOWS { SECURITY_ATTRIBUTES sattr; STARTUPINFOW sinf; HANDLE proc = GetCurrentProcess(); HANDLE oread,eread,iwrite; // creates commandline buffer b = alloc_buffer("\""); val_buffer(b,cmd); buffer_append(b,"\""); int n = val_array_size(vargs); for(i=0;i<n;i++) { value v = val_array_i(vargs,i); val_check(v,string); buffer_append(b," \""); val_buffer(b,v); buffer_append(b,"\""); } wchar_t *name = val_dup_wstring(buffer_to_string(b)); gc_enter_blocking(); p = (vprocess*)malloc(sizeof(vprocess)); // startup process sattr.nLength = sizeof(sattr); sattr.bInheritHandle = TRUE; sattr.lpSecurityDescriptor = NULL; memset(&sinf,0,sizeof(sinf)); sinf.cb = sizeof(sinf); sinf.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; sinf.wShowWindow = SW_NORMAL; CreatePipe(&oread,&sinf.hStdOutput,&sattr,0); CreatePipe(&eread,&sinf.hStdError,&sattr,0); CreatePipe(&sinf.hStdInput,&iwrite,&sattr,0); DuplicateHandle(proc,oread,proc,&p->oread,0,FALSE,DUPLICATE_SAME_ACCESS); DuplicateHandle(proc,eread,proc,&p->eread,0,FALSE,DUPLICATE_SAME_ACCESS); DuplicateHandle(proc,iwrite,proc,&p->iwrite,0,FALSE,DUPLICATE_SAME_ACCESS); CloseHandle(oread); CloseHandle(eread); CloseHandle(iwrite); //printf("Cmd %s\n",val_string(cmd)); if( !CreateProcessW(NULL,name,NULL,NULL,TRUE,0,NULL,NULL,&sinf,&p->pinf) ) { free(p); gc_exit_blocking(); val_throw(alloc_null()); return alloc_null(); } // close unused pipes CloseHandle(sinf.hStdOutput); CloseHandle(sinf.hStdError); CloseHandle(sinf.hStdInput); gc_exit_blocking(); } #else char **argv = (char**)malloc(sizeof(char*)*(val_array_size(vargs)+2)); argv[0] = strdup(val_string(cmd)); for(i=0;i<val_array_size(vargs);i++) { value v = val_array_i(vargs,i); val_check(v,string); argv[i+1] = strdup(val_string(v)); } argv[i+1] = NULL; int input[2], output[2], error[2]; if( pipe(input) || pipe(output) || pipe(error) ) return alloc_null(); p = (vprocess*)malloc(sizeof(vprocess)); p->pid = fork(); if( p->pid == -1 ) return alloc_null(); gc_enter_blocking(); // child if( p->pid == 0 ) { close(input[1]); close(output[0]); close(error[0]); dup2(input[0],0); dup2(output[1],1); dup2(error[1],2); execvp(val_string(cmd),argv); fprintf(stderr,"Command not found : %s\n",val_string(cmd)); exit(1); } // parent for(i=0;i<=val_array_size(vargs);i++) free(argv[i]); free(argv); do_close(input[0]); do_close(output[1]); do_close(error[1]); p->iwrite = input[1]; p->oread = output[0]; p->eread = error[0]; gc_exit_blocking(); # endif { value vp = alloc_abstract(k_process,p); val_gc(vp,free_process); return vp; } }
void api_val_gc_ptr(void * arg1,hxPtrFinalizer arg2) { val_gc( (value)arg1, (finalizer)arg2 ); }
/** process_run_raw : cmd:string -> 'process <doc> Start a process using a command. The input string contains the command as well as the arguments. Shell meta-characters will not be auto escaped/quoted. </doc> **/ CAMLprim value process_run_raw( value cmd ) { int i; vprocess *p; val_check(cmd,string); char* cmdStr = val_string(cmd); # ifdef _WIN32 { SECURITY_ATTRIBUTES sattr; STARTUPINFO sinf; HANDLE proc = GetCurrentProcess(); HANDLE oread,eread,iwrite; // creates commandline buffer b = alloc_buffer(NULL); char *sargs; buffer_append_char(b,'"'); char* cmdexe = getenv("COMSPEC"); if (!cmdexe) cmdexe = "cmd.exe"; buffer_append_str(b,cmdexe); buffer_append_char(b,'"'); buffer_append_str(b,"/C \""); buffer_append_str(b,cmdStr); buffer_append_char(b,'"'); sargs = buffer_to_string(b); p = (vprocess*)alloc_private(sizeof(vprocess)); // startup process sattr.nLength = sizeof(sattr); sattr.bInheritHandle = TRUE; sattr.lpSecurityDescriptor = NULL; memset(&sinf,0,sizeof(sinf)); sinf.cb = sizeof(sinf); sinf.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; sinf.wShowWindow = SW_HIDE; CreatePipe(&oread,&sinf.hStdOutput,&sattr,0); CreatePipe(&eread,&sinf.hStdError,&sattr,0); CreatePipe(&sinf.hStdInput,&iwrite,&sattr,0); DuplicateHandle(proc,oread,proc,&p->oread,0,FALSE,DUPLICATE_SAME_ACCESS); DuplicateHandle(proc,eread,proc,&p->eread,0,FALSE,DUPLICATE_SAME_ACCESS); DuplicateHandle(proc,iwrite,proc,&p->iwrite,0,FALSE,DUPLICATE_SAME_ACCESS); CloseHandle(oread); CloseHandle(eread); CloseHandle(iwrite); if( !CreateProcess(NULL,val_string(sargs),NULL,NULL,TRUE,0,NULL,NULL,&sinf,&p->pinf) ) { CloseHandle(p->eread); CloseHandle(p->oread); CloseHandle(p->iwrite); free(sargs); neko_error(); } free(sargs); // close unused pipes CloseHandle(sinf.hStdOutput); CloseHandle(sinf.hStdError); CloseHandle(sinf.hStdInput); } # else char **argv = (char**)alloc_private(sizeof(char*)*4); argv[0] = cmd = "/bin/sh"; argv[1] = "-c"; argv[2] = cmdStr; argv[3] = NULL; int input[2], output[2], error[2]; if( pipe(input) || pipe(output) || pipe(error) ) neko_error(); p = (vprocess*)alloc_private(sizeof(vprocess)); p->pid = fork(); if( p->pid == -1 ) { do_close(input[0]); do_close(input[1]); do_close(output[0]); do_close(output[1]); do_close(error[0]); do_close(error[1]); neko_error(); } // child if( p->pid == 0 ) { close(input[1]); close(output[0]); close(error[0]); dup2(input[0],0); dup2(output[1],1); dup2(error[1],2); execvp(val_string(cmd),argv); fprintf(stderr,"Command not found : %s\n",val_string(cmd)); exit(1); } // parent do_close(input[0]); do_close(output[1]); do_close(error[1]); p->iwrite = input[1]; p->oread = output[0]; p->eread = error[0]; # endif { value vp = alloc_abstract(k_process,p); val_gc(vp,free_process); return vp; } }