zval *samphp::call(char *fn, char *argspec, va_list ap TSRMLS_DC) { zval *rrv = NULL; zend_try { // convert the function name to a zval zval *function_name; MAKE_STD_ZVAL(function_name); ZVAL_STRING(function_name, fn, 0); // parse the parameter list zval **params = NULL; int len = strlen(argspec); if(len > 0) params = new zval* [strlen(argspec)]; zend_uint count; if (parse_args(params, &count, argspec, ap) != SUCCESS) { error_wrap(0, "Error parsing args for function %s", fn); for(unsigned int i = 0; i < count; i++) if(params[i]) zval_ptr_dtor(¶ms[i]); efree(function_name); status = FAIL; } if(status != FAIL) { zval *rv; MAKE_STD_ZVAL(rv); if(call_user_function(EG(function_table), NULL, function_name, rv, count, params TSRMLS_CC) != SUCCESS) { error_wrap(0, "calling function %s\n", fn); for(unsigned int i = 0; i < count; i++) if(params[i]) zval_ptr_dtor(¶ms[i]); efree(function_name); status = FAIL; } if(status != FAIL) { for(unsigned int i = 0; i < count; i++) if(params[i]) zval_ptr_dtor(¶ms[i]); efree(function_name); rrv = rv; } } delete params; } zend_catch { error_wrap(0, "preparing function %s\n", fn); status = FAIL; } zend_end_try() { } return rrv; }
int main(void) { struct itimerval it; struct timespec ts; int retval; /* Handle SIGALRM */ signal(SIGALRM, &sigalrm_handler); /* Generate a SIGALRM as soon as possible. */ it.it_value.tv_sec = 0; it.it_value.tv_usec = 1; it.it_interval.tv_sec = 0; it.it_interval.tv_usec = 0; error_wrap(setitimer(ITIMER_REAL, &it, NULL), "setitimer"); /* * Wait for the alarm to be generated and delivered, giving plenty of * leeway. */ ts.tv_sec = 1; ts.tv_nsec = 0; while ((retval = nanosleep(&ts, &ts)) == -1 && errno == EINTR) ; error_wrap(retval, "nanosleep"); if (sigalrm_received) { printf("SIGALRM received; good.\n"); return 0; } else { printf("SIGALRM was lost.\n"); return 1; } }
int main(void) { sigset_t alrm_set, pending_set; struct timespec ts; int retval; /* Handle SIGALRM */ signal(SIGALRM, ¬e_sigalrm); /* Block SIGALRM */ error_wrap(sigemptyset(&alrm_set), "sigemptyset"); error_wrap(sigaddset(&alrm_set, SIGALRM), "sigaddset"); error_wrap(sigprocmask(SIG_BLOCK, &alrm_set, NULL), "sigprocmask"); /* Generate a SIGALRM after about a second. */ alarm(1); /* Wait for the alarm to be generated, giving plenty of leeway. */ ts.tv_sec = 2; ts.tv_nsec = 0; while ((retval = nanosleep(&ts, &ts)) == -1 && errno == EINTR) ; error_wrap(retval, "nanosleep"); error_wrap(sigpending(&pending_set), "sigpending"); if (sigismember(&pending_set, SIGALRM)) { printf("SIGALRM pending; good.\n"); } else { printf("SIGALRM not pending?!?\n"); return 1; } /* * Unblock the signal, allowing delivery. SUSv3 says: * * If there are any pending unblocked signals after the call to * sigprocmask(), at least one of those signals shall be delivered * before the call to sigprocmask() returns. * * Thus in the absence of other signals, sigalrm_received should be set * after this line. */ error_wrap(sigprocmask(SIG_UNBLOCK, &alrm_set, NULL), "sigprocmask"); if (sigalrm_received) { printf("SIGALRM received; good.\n"); return 0; } else { printf("SIGALRM was lost.\n"); return 1; } return 0; }