static VALUE ossl_ocspbres_add_status(VALUE self, VALUE cid, VALUE status, VALUE reason, VALUE revtime, VALUE thisupd, VALUE nextupd, VALUE ext) { OCSP_BASICRESP *bs; OCSP_SINGLERESP *single; OCSP_CERTID *id; int st, rsn; ASN1_TIME *ths, *nxt, *rev; int error, i, rstatus = 0; VALUE tmp; st = NUM2INT(status); rsn = NIL_P(status) ? 0 : NUM2INT(reason); if(!NIL_P(ext)){ /* All ary's members should be X509Extension */ Check_Type(ext, T_ARRAY); for (i = 0; i < RARRAY_LEN(ext); i++) OSSL_Check_Kind(RARRAY_PTR(ext)[i], cX509Ext); } error = 0; ths = nxt = rev = NULL; if(!NIL_P(revtime)){ tmp = rb_protect(rb_Integer, revtime, &rstatus); if(rstatus) goto err; rev = X509_gmtime_adj(NULL, NUM2INT(tmp)); } tmp = rb_protect(rb_Integer, thisupd, &rstatus); if(rstatus) goto err; ths = X509_gmtime_adj(NULL, NUM2INT(tmp)); tmp = rb_protect(rb_Integer, nextupd, &rstatus); if(rstatus) goto err; nxt = X509_gmtime_adj(NULL, NUM2INT(tmp)); GetOCSPBasicRes(self, bs); SafeGetOCSPCertId(cid, id); if(!(single = OCSP_basic_add1_status(bs, id, st, rsn, rev, ths, nxt))){ error = 1; goto err; } if(!NIL_P(ext)){ X509_EXTENSION *x509ext; sk_X509_EXTENSION_pop_free(single->singleExtensions, X509_EXTENSION_free); single->singleExtensions = NULL; for(i = 0; i < RARRAY_LEN(ext); i++){ x509ext = DupX509ExtPtr(RARRAY_PTR(ext)[i]); if(!OCSP_SINGLERESP_add_ext(single, x509ext, -1)){ X509_EXTENSION_free(x509ext); error = 1; goto err; } X509_EXTENSION_free(x509ext); } } err: ASN1_TIME_free(ths); ASN1_TIME_free(nxt); ASN1_TIME_free(rev); if(error) ossl_raise(eOCSPError, NULL); if(rstatus) rb_jump_tag(rstatus); return self; }
/* * call-seq: * remote.fetch(refspecs = nil, options = {}) -> hash * * Downloads new data from the remote for the given +refspecs+ and updates tips. * * You can optionally pass in an alternative list of +refspecs+ to use instead of the fetch * refspecs already configured for +remote+. * * Returns a hash containing statistics for the fetch operation. * * The following options can be passed in the +options+ Hash: * * :credentials :: * The credentials to use for the fetch operation. Can be either an instance of one * of the Rugged::Credentials types, or a proc returning one of the former. * The proc will be called with the +url+, the +username+ from the url (if applicable) and * a list of applicable credential types. * * :progress :: * A callback that will be executed with the textual progress received from the remote. * This is the text send over the progress side-band (ie. the "counting objects" output). * * :transfer_progress :: * A callback that will be executed to report clone progress information. It will be passed * the amount of +total_objects+, +indexed_objects+, +received_objects+, +local_objects+, * +total_deltas+, +indexed_deltas+ and +received_bytes+. * * :update_tips :: * A callback that will be executed each time a reference is updated locally. It will be * passed the +refname+, +old_oid+ and +new_oid+. * * :message :: * The message to insert into the reflogs. Defaults to "fetch". * * :signature :: * The signature to be used for updating the reflogs. * * Example: * * remote = Rugged::Remote.lookup(@repo, 'origin') * remote.fetch({ * transfer_progress: lambda { |total_objects, indexed_objects, received_objects, local_objects, total_deltas, indexed_deltas, received_bytes| * # ... * } * }) */ static VALUE rb_git_remote_fetch(int argc, VALUE *argv, VALUE self) { git_remote *remote, *tmp_remote = NULL; git_repository *repo; git_signature *signature = NULL; git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT; struct rugged_remote_cb_payload payload = { Qnil, Qnil, Qnil, Qnil, Qnil, 0 }; char *log_message = NULL; int error, i; VALUE rb_options, rb_refspecs, rb_result = Qnil, rb_repo = rugged_owner(self); rb_scan_args(argc, argv, "01:", &rb_refspecs, &rb_options); if (!NIL_P(rb_refspecs)) { Check_Type(rb_refspecs, T_ARRAY); for (i = 0; i < RARRAY_LEN(rb_refspecs); ++i) { VALUE rb_refspec = rb_ary_entry(rb_refspecs, i); Check_Type(rb_refspec, T_STRING); } } Data_Get_Struct(self, git_remote, remote); rugged_check_repo(rb_repo); Data_Get_Struct(rb_repo, git_repository, repo); if (!NIL_P(rb_options)) { VALUE rb_val = rb_hash_aref(rb_options, CSTR2SYM("signature")); if (!NIL_P(rb_val)) signature = rugged_signature_get(rb_val, repo); rb_val = rb_hash_aref(rb_options, CSTR2SYM("message")); if (!NIL_P(rb_val)) log_message = StringValueCStr(rb_val); rugged_remote_init_callbacks_and_payload_from_options(rb_options, &callbacks, &payload); } if ((error = git_remote_dup(&tmp_remote, remote)) || (error = git_remote_set_callbacks(tmp_remote, &callbacks))) goto cleanup; if (!NIL_P(rb_refspecs)) { git_remote_clear_refspecs(tmp_remote); for (i = 0; !error && i < RARRAY_LEN(rb_refspecs); ++i) { VALUE rb_refspec = rb_ary_entry(rb_refspecs, i); if ((error = git_remote_add_fetch(tmp_remote, StringValueCStr(rb_refspec)))) goto cleanup; } } if ((error = git_remote_fetch(tmp_remote, signature, log_message)) == GIT_OK) { const git_transfer_progress *stats = git_remote_stats(tmp_remote); rb_result = rb_hash_new(); rb_hash_aset(rb_result, CSTR2SYM("total_objects"), UINT2NUM(stats->total_objects)); rb_hash_aset(rb_result, CSTR2SYM("indexed_objects"), UINT2NUM(stats->indexed_objects)); rb_hash_aset(rb_result, CSTR2SYM("received_objects"), UINT2NUM(stats->received_objects)); rb_hash_aset(rb_result, CSTR2SYM("local_objects"), UINT2NUM(stats->local_objects)); rb_hash_aset(rb_result, CSTR2SYM("total_deltas"), UINT2NUM(stats->total_deltas)); rb_hash_aset(rb_result, CSTR2SYM("indexed_deltas"), UINT2NUM(stats->indexed_deltas)); rb_hash_aset(rb_result, CSTR2SYM("received_bytes"), INT2FIX(stats->received_bytes)); } cleanup: git_signature_free(signature); git_remote_free(tmp_remote); if (payload.exception) rb_jump_tag(payload.exception); rugged_exception_check(error); return rb_result; }
/* * This is the method that actually puts your code into a loop and allows it * to run as a service. The code that is actually run while in the mainloop * is what you defined in your own Daemon#service_main method. */ static VALUE daemon_mainloop(VALUE self) { DWORD ThreadId; HANDLE events[2]; DWORD index; VALUE result, EventHookHash; int status = 0; dwServiceState = 0; // Redirect STDIN, STDOUT and STDERR to the NUL device if they're still // associated with a tty. This helps newbs avoid Errno::EBADF errors. if(rb_funcall(rb_stdin, rb_intern("isatty"), 0) == Qtrue) rb_funcall(rb_stdin, rb_intern("reopen"), 1, rb_str_new2("NUL")); if(rb_funcall(rb_stdout, rb_intern("isatty"), 0) == Qtrue) rb_funcall(rb_stdout, rb_intern("reopen"), 1, rb_str_new2("NUL")); if(rb_funcall(rb_stderr, rb_intern("isatty"), 0) == Qtrue) rb_funcall(rb_stderr, rb_intern("reopen"), 1, rb_str_new2("NUL")); // Use a markable instance variable to prevent the garbage collector // from freeing the hash before Ruby_Service_Ctrl exits, or just // at any ole time while running the service EventHookHash = rb_hash_new(); rb_ivar_set(self, rb_intern("@event_hooks"), EventHookHash); // Event hooks if(rb_respond_to(self, rb_intern("service_stop"))){ rb_hash_aset(EventHookHash, INT2NUM(SERVICE_CONTROL_STOP), rb_ary_new3(2, self, INT2NUM(rb_intern("service_stop")))); } if(rb_respond_to(self, rb_intern("service_pause"))){ rb_hash_aset(EventHookHash, INT2NUM(SERVICE_CONTROL_PAUSE), rb_ary_new3(2, self, INT2NUM(rb_intern("service_pause")))); } if(rb_respond_to(self, rb_intern("service_resume"))){ rb_hash_aset(EventHookHash, INT2NUM(SERVICE_CONTROL_CONTINUE), rb_ary_new3(2, self, INT2NUM(rb_intern("service_resume")))); } if(rb_respond_to(self, rb_intern("service_interrogate"))){ rb_hash_aset(EventHookHash, INT2NUM(SERVICE_CONTROL_INTERROGATE), rb_ary_new3(2, self, INT2NUM(rb_intern("service_interrogate")))); } if(rb_respond_to(self, rb_intern("service_shutdown"))){ rb_hash_aset(EventHookHash, INT2NUM(SERVICE_CONTROL_SHUTDOWN), rb_ary_new3(2, self, INT2NUM(rb_intern("service_shutdown")))); } #ifdef SERVICE_CONTROL_PARAMCHANGE if(rb_respond_to(self, rb_intern("service_paramchange"))){ rb_hash_aset(EventHookHash, INT2NUM(SERVICE_CONTROL_PARAMCHANGE), rb_ary_new3(2, self, INT2NUM(rb_intern("service_paramchange")))); } #endif #ifdef SERVICE_CONTROL_NETBINDADD if(rb_respond_to(self, rb_intern("service_netbindadd"))){ rb_hash_aset(EventHookHash, INT2NUM(SERVICE_CONTROL_NETBINDADD), rb_ary_new3(2, self, INT2NUM(rb_intern("service_netbindadd")))); } #endif #ifdef SERVICE_CONTROL_NETBINDREMOVE if(rb_respond_to(self, rb_intern("service_netbindremove"))){ rb_hash_aset(EventHookHash, INT2NUM(SERVICE_CONTROL_NETBINDREMOVE), rb_ary_new3(2, self, INT2NUM(rb_intern("service_netbindremove")))); } #endif #ifdef SERVICE_CONTROL_NETBINDENABLE if(rb_respond_to(self, rb_intern("service_netbindenable"))){ rb_hash_aset(EventHookHash, INT2NUM(SERVICE_CONTROL_NETBINDENABLE), rb_ary_new3(2, self, INT2NUM(rb_intern("service_netbindenable")))); } #endif #ifdef SERVICE_CONTROL_NETBINDDISABLE if(rb_respond_to(self, rb_intern("service_netbinddisable"))){ rb_hash_aset(EventHookHash, INT2NUM(SERVICE_CONTROL_NETBINDDISABLE), rb_ary_new3(2, self, INT2NUM(rb_intern("service_netbinddisable")))); } #endif // Calling init here so that init failures never even tries to // start the service... of course that means that init methods // must be very quick, because the SCM will be receiving no // START_PENDING messages while init's running - I may fix this // later if(rb_respond_to(self, rb_intern("service_init"))) rb_funcall(self, rb_intern("service_init"),0); // Create the event to signal the service to start. hStartEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if(hStartEvent == NULL) rb_raise(cDaemonError, ErrorDescription(GetLastError())); // Create the event to signal the service to stop. hStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if(hStopEvent == NULL) rb_raise(cDaemonError, ErrorDescription(GetLastError())); // Create the event to signal the service that stop has completed hStopCompletedEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if(hStopCompletedEvent == NULL) rb_raise(cDaemonError, ErrorDescription(GetLastError())); // Create Thread for service main hThread = CreateThread(NULL, 0, ThreadProc, 0, 0, &ThreadId); if(hThread == INVALID_HANDLE_VALUE) rb_raise(cDaemonError, ErrorDescription(GetLastError())); events[0] = hThread; events[1] = hStartEvent; // wait for Service_Main function to either start the service OR terminate while((index = WaitForMultipleObjects(2,events,FALSE,1000)) == WAIT_TIMEOUT) { } // thread exited, so the show is off if(index == WAIT_OBJECT_0) rb_raise(cDaemonError, "Service_Main thread exited abnormally"); // from this point onward, stopevent must be triggered! // Create the green thread to poll for Service_Ctrl events rb_thread_create(Ruby_Service_Ctrl, (void *)self); result = rb_protect(daemon_mainloop_protect, self, &status); // service_main raised an exception if(status){ daemon_mainloop_ensure(self); rb_jump_tag(status); } // service_main exited cleanly return daemon_mainloop_ensure(self); }
static VALUE zipruby_archive_s_open_buffer(int argc, VALUE *argv, VALUE self) { VALUE buffer, flags, comp_level; VALUE archive; struct zipruby_archive *p_archive; void *data = NULL; int len = 0, i_flags = 0; int errorp; int i_comp_level = Z_BEST_COMPRESSION; int buffer_is_temporary = 0; rb_scan_args(argc, argv, "03", &buffer, &flags, &comp_level); if (FIXNUM_P(buffer) && NIL_P(comp_level)) { comp_level = flags; flags = buffer; buffer = Qnil; } if (!NIL_P(flags)) { i_flags = NUM2INT(flags); } if (!NIL_P(comp_level)) { i_comp_level = NUM2INT(comp_level); if (i_comp_level != Z_DEFAULT_COMPRESSION && i_comp_level != Z_NO_COMPRESSION && (i_comp_level < Z_BEST_SPEED || Z_BEST_COMPRESSION < i_comp_level)) { rb_raise(rb_eArgError, "Wrong compression level %d", i_comp_level); } } if (i_flags & ZIP_CREATE) { if (!NIL_P(buffer)) { Check_Type(buffer, T_STRING); } else { buffer = rb_str_new("", 0); buffer_is_temporary = 1; } i_flags = (i_flags | ZIP_TRUNCATE); } else if (TYPE(buffer) == T_STRING) { data = RSTRING_PTR(buffer); len = RSTRING_LEN(buffer); } else if (rb_obj_is_instance_of(buffer, rb_cProc)) { data = (void *) buffer; len = -1; } else { rb_raise(rb_eTypeError, "wrong argument type %s (expected String or Proc)", rb_class2name(CLASS_OF(buffer))); } archive = rb_funcall(Archive, rb_intern("new"), 0); Data_Get_Struct(archive, struct zipruby_archive, p_archive); if ((p_archive->tmpfilnam = zipruby_tmpnam(data, len)) == NULL) { rb_raise(Error, "Open archive failed: Failed to create temporary file"); } if ((p_archive->archive = zip_open(p_archive->tmpfilnam, i_flags, &errorp)) == NULL) { char errstr[ERRSTR_BUFSIZE]; zip_error_to_str(errstr, ERRSTR_BUFSIZE, errorp, errno); rb_raise(Error, "Open archive failed: %s", errstr); } // p_archive->archive->comp_level = i_comp_level; p_archive->path = rb_str_new2(p_archive->tmpfilnam); p_archive->flags = i_flags; p_archive->buffer = buffer; p_archive->sources = rb_ary_new(); if (rb_block_given_p()) { VALUE retval; int status; retval = rb_protect(rb_yield, archive, &status); zipruby_archive_close(archive); if (status != 0) { rb_jump_tag(status); } return buffer_is_temporary ? buffer : retval; } else { return archive; } }
void initialize_semaphore_set(semian_resource_t* res, const char* id_str, long permissions, int tickets, double quota) { res->key = generate_key(id_str); res->strkey = (char*) malloc((2 /*for 0x*/+ sizeof(uint64_t) /*actual key*/+ 1 /*null*/) * sizeof(char)); sprintf(res->strkey, "0x%08x", (unsigned int) res->key); res->sem_id = semget(res->key, SI_NUM_SEMAPHORES, IPC_CREAT | IPC_EXCL | permissions); /* This approach is based on http://man7.org/tlpi/code/online/dist/svsem/svsem_good_init.c.html which avoids race conditions when initializing semaphore sets. */ if (res->sem_id != -1) { // Happy path - we are the first worker, initialize the semaphore set. initialize_new_semaphore_values(res->sem_id, permissions); } else { // Something went wrong if (errno != EEXIST) { raise_semian_syscall_error("semget() failed to initialize semaphore values", errno); } else { // The semaphore set already exists, ensure it is initialized res->sem_id = wait_for_new_semaphore_set(res->key, permissions); } } set_semaphore_permissions(res->sem_id, permissions); /* Ensure that a worker for this process is registered. Note that from ruby we ensure that at most one worker may be registered per process. */ if (perform_semop(res->sem_id, SI_SEM_REGISTERED_WORKERS, 1, SEM_UNDO, NULL) == -1) { rb_raise(eInternal, "error incrementing registered workers, errno: %d (%s)", errno, strerror(errno)); } int state = 0; sem_meta_lock(res->sem_id); // Sets otime for the first time by acquiring the sem lock configure_tickets_args_t configure_tickets_args = (configure_tickets_args_t){ .sem_id = res->sem_id, .tickets = tickets, .quota = quota, }; rb_protect( configure_tickets, (VALUE)&configure_tickets_args, &state); sem_meta_unlock(res->sem_id); if (state) { rb_jump_tag(state); } } void set_semaphore_permissions(int sem_id, long permissions) { union semun sem_opts; struct semid_ds stat_buf; sem_opts.buf = &stat_buf; semctl(sem_id, 0, IPC_STAT, sem_opts); if ((stat_buf.sem_perm.mode & 0xfff) != permissions) { stat_buf.sem_perm.mode &= ~0xfff; stat_buf.sem_perm.mode |= permissions; semctl(sem_id, 0, IPC_SET, sem_opts); } } int perform_semop(int sem_id, short index, short op, short flags, struct timespec *ts) { struct sembuf buf = { 0 }; buf.sem_num = index; buf.sem_op = op; buf.sem_flg = flags; if (ts) { return semtimedop(sem_id, &buf, 1, ts); } else { return semop(sem_id, &buf, 1); } } int get_sem_val(int sem_id, int sem_index) { int ret = semctl(sem_id, sem_index, GETVAL); if (ret == -1) { rb_raise(eInternal, "error getting value of %s for sem %d, errno: %d (%s)", SEMINDEX_STRING[sem_index], sem_id, errno, strerror(errno)); } return ret; }
/* * call-seq: * parser.parse(yaml) * * Parse the YAML document contained in +yaml+. Events will be called on * the handler set on the parser instance. * * See Psych::Parser and Psych::Parser#handler */ static VALUE parse(int argc, VALUE *argv, VALUE self) { VALUE yaml, path; yaml_parser_t * parser; yaml_event_t event; int done = 0; int tainted = 0; int state = 0; int parser_encoding = YAML_ANY_ENCODING; #ifdef HAVE_RUBY_ENCODING_H int encoding = rb_utf8_encindex(); rb_encoding * internal_enc = rb_default_internal_encoding(); #endif VALUE handler = rb_iv_get(self, "@handler"); if (rb_scan_args(argc, argv, "11", &yaml, &path) == 1) { if(rb_respond_to(yaml, id_path)) path = rb_funcall(yaml, id_path, 0); else path = rb_str_new2("<unknown>"); } Data_Get_Struct(self, yaml_parser_t, parser); yaml_parser_delete(parser); yaml_parser_initialize(parser); if (OBJ_TAINTED(yaml)) tainted = 1; if (rb_respond_to(yaml, id_read)) { #ifdef HAVE_RUBY_ENCODING_H yaml = transcode_io(yaml, &parser_encoding); yaml_parser_set_encoding(parser, parser_encoding); #endif yaml_parser_set_input(parser, io_reader, (void *)yaml); if (RTEST(rb_obj_is_kind_of(yaml, rb_cIO))) tainted = 1; } else { StringValue(yaml); #ifdef HAVE_RUBY_ENCODING_H yaml = transcode_string(yaml, &parser_encoding); yaml_parser_set_encoding(parser, parser_encoding); #endif yaml_parser_set_input_string( parser, (const unsigned char *)RSTRING_PTR(yaml), (size_t)RSTRING_LEN(yaml) ); } while(!done) { if(!yaml_parser_parse(parser, &event)) { VALUE exception; exception = make_exception(parser, path); yaml_parser_delete(parser); yaml_parser_initialize(parser); rb_exc_raise(exception); } switch(event.type) { case YAML_STREAM_START_EVENT: { VALUE args[2]; args[0] = handler; args[1] = INT2NUM((long)event.data.stream_start.encoding); rb_protect(protected_start_stream, (VALUE)args, &state); } break; case YAML_DOCUMENT_START_EVENT: { VALUE args[4]; /* Get a list of tag directives (if any) */ VALUE tag_directives = rb_ary_new(); /* Grab the document version */ VALUE version = event.data.document_start.version_directive ? rb_ary_new3( (long)2, INT2NUM((long)event.data.document_start.version_directive->major), INT2NUM((long)event.data.document_start.version_directive->minor) ) : rb_ary_new(); if(event.data.document_start.tag_directives.start) { yaml_tag_directive_t *start = event.data.document_start.tag_directives.start; yaml_tag_directive_t *end = event.data.document_start.tag_directives.end; for(; start != end; start++) { VALUE handle = Qnil; VALUE prefix = Qnil; if(start->handle) { handle = rb_str_new2((const char *)start->handle); if (tainted) OBJ_TAINT(handle); #ifdef HAVE_RUBY_ENCODING_H PSYCH_TRANSCODE(handle, encoding, internal_enc); #endif } if(start->prefix) { prefix = rb_str_new2((const char *)start->prefix); if (tainted) OBJ_TAINT(prefix); #ifdef HAVE_RUBY_ENCODING_H PSYCH_TRANSCODE(prefix, encoding, internal_enc); #endif } rb_ary_push(tag_directives, rb_ary_new3((long)2, handle, prefix)); } } args[0] = handler; args[1] = version; args[2] = tag_directives; args[3] = event.data.document_start.implicit == 1 ? Qtrue : Qfalse; rb_protect(protected_start_document, (VALUE)args, &state); } break; case YAML_DOCUMENT_END_EVENT: { VALUE args[2]; args[0] = handler; args[1] = event.data.document_end.implicit == 1 ? Qtrue : Qfalse; rb_protect(protected_end_document, (VALUE)args, &state); } break; case YAML_ALIAS_EVENT: { VALUE args[2]; VALUE alias = Qnil; if(event.data.alias.anchor) { alias = rb_str_new2((const char *)event.data.alias.anchor); if (tainted) OBJ_TAINT(alias); #ifdef HAVE_RUBY_ENCODING_H PSYCH_TRANSCODE(alias, encoding, internal_enc); #endif } args[0] = handler; args[1] = alias; rb_protect(protected_alias, (VALUE)args, &state); } break; case YAML_SCALAR_EVENT: { VALUE args[7]; VALUE anchor = Qnil; VALUE tag = Qnil; VALUE plain_implicit, quoted_implicit, style; VALUE val = rb_str_new( (const char *)event.data.scalar.value, (long)event.data.scalar.length ); if (tainted) OBJ_TAINT(val); #ifdef HAVE_RUBY_ENCODING_H PSYCH_TRANSCODE(val, encoding, internal_enc); #endif if(event.data.scalar.anchor) { anchor = rb_str_new2((const char *)event.data.scalar.anchor); if (tainted) OBJ_TAINT(anchor); #ifdef HAVE_RUBY_ENCODING_H PSYCH_TRANSCODE(anchor, encoding, internal_enc); #endif } if(event.data.scalar.tag) { tag = rb_str_new2((const char *)event.data.scalar.tag); if (tainted) OBJ_TAINT(tag); #ifdef HAVE_RUBY_ENCODING_H PSYCH_TRANSCODE(tag, encoding, internal_enc); #endif } plain_implicit = event.data.scalar.plain_implicit == 0 ? Qfalse : Qtrue; quoted_implicit = event.data.scalar.quoted_implicit == 0 ? Qfalse : Qtrue; style = INT2NUM((long)event.data.scalar.style); args[0] = handler; args[1] = val; args[2] = anchor; args[3] = tag; args[4] = plain_implicit; args[5] = quoted_implicit; args[6] = style; rb_protect(protected_scalar, (VALUE)args, &state); } break; case YAML_SEQUENCE_START_EVENT: { VALUE args[5]; VALUE anchor = Qnil; VALUE tag = Qnil; VALUE implicit, style; if(event.data.sequence_start.anchor) { anchor = rb_str_new2((const char *)event.data.sequence_start.anchor); if (tainted) OBJ_TAINT(anchor); #ifdef HAVE_RUBY_ENCODING_H PSYCH_TRANSCODE(anchor, encoding, internal_enc); #endif } tag = Qnil; if(event.data.sequence_start.tag) { tag = rb_str_new2((const char *)event.data.sequence_start.tag); if (tainted) OBJ_TAINT(tag); #ifdef HAVE_RUBY_ENCODING_H PSYCH_TRANSCODE(tag, encoding, internal_enc); #endif } implicit = event.data.sequence_start.implicit == 0 ? Qfalse : Qtrue; style = INT2NUM((long)event.data.sequence_start.style); args[0] = handler; args[1] = anchor; args[2] = tag; args[3] = implicit; args[4] = style; rb_protect(protected_start_sequence, (VALUE)args, &state); } break; case YAML_SEQUENCE_END_EVENT: rb_protect(protected_end_sequence, handler, &state); break; case YAML_MAPPING_START_EVENT: { VALUE args[5]; VALUE anchor = Qnil; VALUE tag = Qnil; VALUE implicit, style; if(event.data.mapping_start.anchor) { anchor = rb_str_new2((const char *)event.data.mapping_start.anchor); if (tainted) OBJ_TAINT(anchor); #ifdef HAVE_RUBY_ENCODING_H PSYCH_TRANSCODE(anchor, encoding, internal_enc); #endif } if(event.data.mapping_start.tag) { tag = rb_str_new2((const char *)event.data.mapping_start.tag); if (tainted) OBJ_TAINT(tag); #ifdef HAVE_RUBY_ENCODING_H PSYCH_TRANSCODE(tag, encoding, internal_enc); #endif } implicit = event.data.mapping_start.implicit == 0 ? Qfalse : Qtrue; style = INT2NUM((long)event.data.mapping_start.style); args[0] = handler; args[1] = anchor; args[2] = tag; args[3] = implicit; args[4] = style; rb_protect(protected_start_mapping, (VALUE)args, &state); } break; case YAML_MAPPING_END_EVENT: rb_protect(protected_end_mapping, handler, &state); break; case YAML_NO_EVENT: rb_protect(protected_empty, handler, &state); break; case YAML_STREAM_END_EVENT: rb_protect(protected_end_stream, handler, &state); done = 1; break; } yaml_event_delete(&event); if (state) rb_jump_tag(state); } return self; }
static VALUE rg_replace(gint argc, VALUE *argv, VALUE self) { VALUE rb_string; VALUE rb_replacement; VALUE rb_options; VALUE rb_start_position; VALUE rb_match_options; VALUE rb_literal; GError *error = NULL; gchar *modified_string; const gchar *string; const gchar *replacement; gssize string_len = -1; gint start_position = 0; GRegexMatchFlags match_options = 0; if (rb_block_given_p()) { RGRegexEvalCallbackData data; rb_scan_args(argc, argv, "11", &rb_string, &rb_options); rbg_scan_options(rb_options, "start_position", &rb_start_position, "match_options", &rb_match_options, NULL); string = RVAL2CSTR(rb_string); string_len = RSTRING_LEN(rb_string); if (!NIL_P(rb_start_position)) start_position = NUM2INT(rb_start_position); if (!NIL_P(rb_match_options)) match_options = RVAL2GREGEXMATCHOPTIONSFLAGS(rb_match_options); data.callback = rb_block_proc(); data.status = 0; modified_string = g_regex_replace_eval(_SELF(self), string, string_len, start_position, match_options, rg_regex_eval_callback, &data, &error); if (!(data.status == 0 || data.status == RUBY_TAG_BREAK)) { if (error) g_error_free(error); g_free(modified_string); rb_jump_tag(data.status); } } else { rb_scan_args(argc, argv, "21", &rb_string, &rb_replacement, &rb_options); rbg_scan_options(rb_options, "start_position", &rb_start_position, "match_options", &rb_match_options, "literal", &rb_literal, NULL); string = RVAL2CSTR(rb_string); string_len = RSTRING_LEN(rb_string); replacement = RVAL2CSTR(rb_replacement); if (!NIL_P(rb_start_position)) start_position = NUM2INT(rb_start_position); if (!NIL_P(rb_match_options)) match_options = RVAL2GREGEXMATCHOPTIONSFLAGS(rb_match_options); if (RVAL2CBOOL(rb_literal)) { modified_string = g_regex_replace_literal(_SELF(self), string, string_len, start_position, replacement, match_options, &error); } else { modified_string = g_regex_replace(_SELF(self), string, string_len, start_position, replacement, match_options, &error); } } if (error) RAISE_GERROR(error); return CSTR2RVAL_FREE(modified_string); }
static VALUE fs_watcher_wait_for_change(VALUE self) { FSWatcher *watcher; pthread_t thr; ssize_t ret; int e, interrupted = 0; FSWatcherReadByteData read_data; Data_Get_Struct(self, FSWatcher, watcher); if (watcher->preparation_error) { return Qfalse; } /* Spawn a thread, and let the thread perform the blocking kqueue * wait. When kevent() returns the thread will write its status to the * notification pipe. In the mean time we let the Ruby interpreter wait * on the other side of the pipe for us so that we don't block Ruby * threads. */ e = pthread_create(&thr, NULL, fs_watcher_wait_on_kqueue, watcher); if (e != 0) { errno = e; rb_sys_fail("pthread_create()"); return Qnil; } /* Note that rb_thread_wait() does not wait for the fd when the app * is single threaded, so we must join the thread after we've read * from the notification fd. */ rb_protect(fs_watcher_wait_fd, (VALUE) watcher->notification_fd[0], &interrupted); if (interrupted) { /* We got interrupted so tell the watcher thread to exit. */ ret = write(watcher->interruption_fd[1], "x", 1); if (ret == -1) { e = errno; fs_watcher_real_close(watcher); errno = e; rb_sys_fail("write() to interruption pipe"); return Qnil; } pthread_join(thr, NULL); /* Now clean up stuff. */ fs_watcher_real_close(watcher); rb_jump_tag(interrupted); return Qnil; } read_data.fd = watcher->notification_fd[0]; rb_protect(fs_watcher_read_byte_from_fd, (VALUE) &read_data, &interrupted); if (interrupted) { /* We got interrupted so tell the watcher thread to exit. */ ret = write(watcher->interruption_fd[1], "x", 1); if (ret == -1) { e = errno; fs_watcher_real_close(watcher); errno = e; rb_sys_fail("write() to interruption pipe"); return Qnil; } pthread_join(thr, NULL); /* Now clean up stuff. */ fs_watcher_real_close(watcher); rb_jump_tag(interrupted); return Qnil; } pthread_join(thr, NULL); if (read_data.ret == -1) { fs_watcher_real_close(watcher); errno = read_data.error; rb_sys_fail("read()"); return Qnil; } else if (read_data.ret == 0) { fs_watcher_real_close(watcher); errno = read_data.error; rb_raise(rb_eRuntimeError, "Unknown error: unexpected EOF"); return Qnil; } else if (read_data.byte == 't') { /* termination_fd or interruption_fd became readable */ return Qnil; } else if (read_data.byte == 'f') { /* a file or directory changed */ return Qtrue; } else { fs_watcher_real_close(watcher); errno = read_data.error; rb_raise(rb_eRuntimeError, "Unknown error: unexpected notification data"); return Qnil; } }
static VALUE rb_libarchive_reader_s_open0(int (*archive_open)(struct rb_libarchive_archive_container *, void *), void *arg, int compression, int format, const char *cmd) { VALUE reader; struct rb_libarchive_archive_container *p; int r; reader = rb_funcall(rb_cArchiveReader, rb_intern("new"), 0); Data_Get_Struct(reader, struct rb_libarchive_archive_container, p); if ((p->ar = archive_read_new()) == NULL) { rb_raise(rb_eArchiveError, "Open reader failed: %s", strerror(errno)); } if (cmd != NULL) { r = archive_read_support_compression_program(p->ar, cmd); } else if (compression != -1) { r = archive_read_support_compression(p->ar, compression); } else { r = archive_read_support_compression_all(p->ar); } if (r != ARCHIVE_OK) { char error_string[BUFSIZ]; archive_copy_error_string(p->ar, error_string, BUFSIZ); rb_libarchive_reader_close0(p); rb_raise(rb_eArchiveError, "Support compression failed: %s", error_string); } if (format != -1) { r = archive_read_support_format(p->ar, format); } else { r = archive_read_support_format_all(p->ar); } if (r != ARCHIVE_OK) { char error_string[BUFSIZ]; archive_copy_error_string(p->ar, error_string, BUFSIZ); rb_libarchive_reader_close0(p); rb_raise(rb_eArchiveError, "Support format failed: %s", error_string); } if (archive_open(p, arg) != ARCHIVE_OK) { char error_string[BUFSIZ]; archive_copy_error_string(p->ar, error_string, BUFSIZ); rb_libarchive_reader_close0(p); rb_raise(rb_eArchiveError, "Open reader failed: %s", error_string); } if (rb_block_given_p()) { VALUE retval; int status; retval = rb_protect(rb_yield, reader, &status); rb_libarchive_reader_close0(p); if (status != 0) { rb_jump_tag(status); } return retval; } else { return reader; } }
static VALUE rb_libarchive_reader_read_data(int argc, VALUE *argv, VALUE self) { VALUE v_size; struct rb_libarchive_archive_container *p; char *buff; size_t size = DATA_BUFFER_SIZE; ssize_t n; rb_scan_args(argc, argv, "01", &v_size); if (!NIL_P(v_size)) { size = NUM2INT(v_size); } Data_Get_Struct(self, struct rb_libarchive_archive_container, p); Check_Archive(p); if (p->eof) { return Qnil; } if (rb_block_given_p()) { ssize_t len = 0; int status = 0; buff = xmalloc(size); while ((n = archive_read_data(p->ar, buff, size)) > 0) { rb_protect(rb_yield, rb_str_new(buff, n), &status); if (status != 0) { break; } len += n; } xfree(buff); if (status != 0) { rb_jump_tag(status); } if (n < 0) { rb_raise(rb_eArchiveError, "Read data failed: %s", archive_error_string(p->ar)); } return LONG2NUM(len); } else { VALUE retval = rb_str_new("", 0); buff = xmalloc(size); while ((n = archive_read_data(p->ar, buff, size)) > 0) { rb_str_cat(retval, buff, n); } xfree(buff); if (n < 0) { rb_raise(rb_eArchiveError, "Read data failed: %s", archive_error_string(p->ar)); } return retval; } }
static VALUE each(int argc, VALUE *argv, VALUE self) { struct readerdata *reader; png_infop winfo; png_structp wpng; VALUE opts; int cmp, state; struct each_args args; uint32_t i, height, width; png_byte ctype; unsigned char **scanlines; size_t row_bytes; rb_scan_args(argc, argv, "01", &opts); Data_Get_Struct(self, struct readerdata, reader); raise_if_locked(reader); reader->locked = 1; wpng = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, (png_error_ptr)error, (png_error_ptr)warning); winfo = png_create_info_struct(wpng); png_set_write_fn(wpng, 0, write_data_fn, flush_data_fn); cmp = png_get_channels(reader->png, reader->info); ctype = png_get_color_type(reader->png, reader->info); png_set_IHDR(wpng, winfo, reader->scale_width, reader->scale_height, 8, ctype, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); width = png_get_image_width(reader->png, reader->info); height = png_get_image_height(reader->png, reader->info); row_bytes = png_get_rowbytes(reader->png, reader->info); args.reader = reader; args.wpng = wpng; args.winfo = winfo; args.inwidthbuf = malloc(row_bytes); args.outwidthbuf = malloc(reader->scale_width * cmp); xscaler_init(&args.xs, width, reader->scale_width, cmp, 0); if (png_get_interlace_type(reader->png, reader->info) == PNG_INTERLACE_NONE) { yscaler_init(&args.ys, height, reader->scale_height, reader->scale_width * cmp); rb_protect((VALUE(*)(VALUE))each_interlace_none, (VALUE)&args, &state); yscaler_free(&args.ys); } else { scanlines = malloc(height * sizeof(unsigned char *)); for (i=0; i<height; i++) { scanlines[i] = malloc(row_bytes); } args.scanlines = scanlines; rb_protect((VALUE(*)(VALUE))each_interlace, (VALUE)&args, &state); for (i=0; i<height; i++) { free(scanlines[i]); } free(scanlines); } xscaler_free(&args.xs); free(args.inwidthbuf); free(args.outwidthbuf); png_destroy_write_struct(&wpng, &winfo); if (state) { rb_jump_tag(state); } return self; }