PHP_METHOD(Type, dump) { zval *zoutput = NULL; php_jit_type_t *ptype; php_stream *pstream = NULL; JIT_WIN32_NOT_IMPLEMENTED(); if (php_jit_parameters("|r", &zoutput) != SUCCESS) { php_jit_exception("unexpected parameters, expected ([resource output = STDOUT])"); return; } ptype = PHP_JIT_FETCH_TYPE(getThis()); if (!zoutput) { jit_dump_type(stdout, ptype->type); return; } php_stream_from_zval(pstream, zoutput); if (php_stream_can_cast(pstream, PHP_STREAM_AS_STDIO|PHP_STREAM_CAST_TRY_HARD) == SUCCESS) { FILE *stdio; if (php_stream_cast(pstream, PHP_STREAM_AS_STDIO, (void**)&stdio, 0) == SUCCESS) { jit_dump_type(stdio, ptype->type); } } }
int swoole_convert_to_fd(zval *zfd) { php_stream *stream; int socket_fd; #ifdef SWOOLE_SOCKETS_SUPPORT php_socket *php_sock; #endif if (Z_TYPE_P(zfd) == IS_RESOURCE) { if (SW_ZEND_FETCH_RESOURCE_NO_RETURN(stream, php_stream *, &zfd, -1, NULL, php_file_le_stream())) { if (php_stream_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL, (void* )&socket_fd, 1) != SUCCESS || socket_fd < 0) { return SW_ERR; } } else { #ifdef SWOOLE_SOCKETS_SUPPORT if (SW_ZEND_FETCH_RESOURCE_NO_RETURN(php_sock, php_socket *, &zfd, -1, NULL, php_sockets_le_socket())) { socket_fd = php_sock->bsd_socket; } else { swoole_php_fatal_error(E_WARNING, "fd argument must be either valid PHP stream or valid PHP socket resource"); return SW_ERR; } #else swoole_php_fatal_error(E_WARNING, "fd argument must be valid PHP stream resource"); return SW_ERR; #endif }
/* Checks if the provides resource is a stream and if it provides a file descriptor */ static int php_posix_stream_get_fd(zval *zfp, int *fd) /* {{{ */ { php_stream *stream; php_stream_from_zval_no_verify(stream, zfp); if (stream == NULL) { php_error_docref(NULL, E_WARNING, "expects argument 1 to be a valid stream resource"); return 0; } if (php_stream_can_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT) == SUCCESS) { php_stream_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT, (void*)fd, 0); } else if (php_stream_can_cast(stream, PHP_STREAM_AS_FD) == SUCCESS) { php_stream_cast(stream, PHP_STREAM_AS_FD, (void*)fd, 0); } else { php_error_docref(NULL, E_WARNING, "could not use stream of type '%s'", stream->ops->label); return 0; } return 1; }
/** * Get access to the internal filedescriptor * Note that not every stream is always associated with a filedescriptor, * in which case this function returns -1 * @return int */ int Stream::fd() const { // the return value int retval = -1; // cast the stream to a filedescriptor, the cast-internal parameter is supposed to be to get // rid of warnings about buffered data (this code was copied from streamfuncs.c). We use // "FOR_SELECT" casting, as that is the most simple operations (without "FOR_SELECT" it flushes too) auto result = php_stream_cast(_stream, PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL, (void **)&retval, 0); // on failure we return -1 return result == SUCCESS ? retval : -1; }
static inline long hs_response_select(php_stream *stream, long timeout TSRMLS_DC) { php_socket_t max_fd = 0; int retval, max_set_count = 0; struct timeval tv; struct timeval *tv_p = NULL; fd_set fds; FD_ZERO(&fds); if (php_stream_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT|PHP_STREAM_CAST_INTERNAL, (void*)&max_fd, 1) == SUCCESS && max_fd != -1) { PHP_SAFE_FD_SET(max_fd, &fds); max_set_count++; } PHP_SAFE_MAX_FD(max_fd, max_set_count); if (timeout > 0) { tv.tv_sec = timeout; tv.tv_usec = 0; tv_p = &tv; } retval = php_select(max_fd+1, &fds, NULL, NULL, tv_p); if (retval == -1) { zend_error(E_WARNING, "[HandlerSocket] unable to select"); return -1; } if (!PHP_SAFE_FD_ISSET(max_fd, &fds)) { return -1; } return 0; }
/* {{{ php_stream_cast */ PHPAPI int _php_stream_cast(php_stream *stream, int castas, void **ret, int show_err) { int flags = castas & PHP_STREAM_CAST_MASK; castas &= ~PHP_STREAM_CAST_MASK; /* synchronize our buffer (if possible) */ if (ret && castas != PHP_STREAM_AS_FD_FOR_SELECT) { php_stream_flush(stream); if (stream->ops->seek && (stream->flags & PHP_STREAM_FLAG_NO_SEEK) == 0) { zend_off_t dummy; stream->ops->seek(stream, stream->position, SEEK_SET, &dummy); stream->readpos = stream->writepos = 0; } } /* filtered streams can only be cast as stdio, and only when fopencookie is present */ if (castas == PHP_STREAM_AS_STDIO) { if (stream->stdiocast) { if (ret) { *(FILE**)ret = stream->stdiocast; } goto exit_success; } /* if the stream is a stdio stream let's give it a chance to respond * first, to avoid doubling up the layers of stdio with an fopencookie */ if (php_stream_is(stream, PHP_STREAM_IS_STDIO) && stream->ops->cast && !php_stream_is_filtered(stream) && stream->ops->cast(stream, castas, ret) == SUCCESS ) { goto exit_success; } #if HAVE_FOPENCOOKIE /* if just checking, say yes we can be a FILE*, but don't actually create it yet */ if (ret == NULL) { goto exit_success; } { char fixed_mode[5]; php_stream_mode_sanitize_fdopen_fopencookie(stream, fixed_mode); *(FILE**)ret = fopencookie(stream, fixed_mode, PHP_STREAM_COOKIE_FUNCTIONS); } if (*ret != NULL) { zend_off_t pos; stream->fclose_stdiocast = PHP_STREAM_FCLOSE_FOPENCOOKIE; /* If the stream position is not at the start, we need to force * the stdio layer to believe it's real location. */ pos = php_stream_tell(stream); if (pos > 0) { zend_fseek(*ret, pos, SEEK_SET); } goto exit_success; } /* must be either: a) programmer error b) no memory -> lets bail */ php_error_docref(NULL, E_ERROR, "fopencookie failed"); return FAILURE; #endif if (!php_stream_is_filtered(stream) && stream->ops->cast && stream->ops->cast(stream, castas, NULL) == SUCCESS) { if (FAILURE == stream->ops->cast(stream, castas, ret)) { return FAILURE; } goto exit_success; } else if (flags & PHP_STREAM_CAST_TRY_HARD) { php_stream *newstream; newstream = php_stream_fopen_tmpfile(); if (newstream) { int retcopy = php_stream_copy_to_stream_ex(stream, newstream, PHP_STREAM_COPY_ALL, NULL); if (retcopy != SUCCESS) { php_stream_close(newstream); } else { int retcast = php_stream_cast(newstream, castas | flags, (void **)ret, show_err); if (retcast == SUCCESS) { rewind(*(FILE**)ret); } /* do some specialized cleanup */ if ((flags & PHP_STREAM_CAST_RELEASE)) { php_stream_free(stream, PHP_STREAM_FREE_CLOSE_CASTED); } /* TODO: we probably should be setting .stdiocast and .fclose_stdiocast or * we may be leaking the FILE*. Needs investigation, though. */ return retcast; } } } } if (php_stream_is_filtered(stream)) { php_error_docref(NULL, E_WARNING, "cannot cast a filtered stream on this system"); return FAILURE; } else if (stream->ops->cast && stream->ops->cast(stream, castas, ret) == SUCCESS) { goto exit_success; } if (show_err) { /* these names depend on the values of the PHP_STREAM_AS_XXX defines in php_streams.h */ static const char *cast_names[4] = { "STDIO FILE*", "File Descriptor", "Socket Descriptor", "select()able descriptor" }; php_error_docref(NULL, E_WARNING, "cannot represent a stream of type %s as a %s", stream->ops->label, cast_names[castas]); } return FAILURE; exit_success: if ((stream->writepos - stream->readpos) > 0 && stream->fclose_stdiocast != PHP_STREAM_FCLOSE_FOPENCOOKIE && (flags & PHP_STREAM_CAST_INTERNAL) == 0 ) { /* the data we have buffered will be lost to the third party library that * will be accessing the stream. Emit a warning so that the end-user will * know that they should try something else */ php_error_docref(NULL, E_WARNING, ZEND_LONG_FMT " bytes of buffered data lost during stream conversion!", (zend_long)(stream->writepos - stream->readpos)); } if (castas == PHP_STREAM_AS_STDIO && ret) { stream->stdiocast = *(FILE**)ret; } if (flags & PHP_STREAM_CAST_RELEASE) { php_stream_free(stream, PHP_STREAM_FREE_CLOSE_CASTED); } return SUCCESS; }
int php_yar_socket_send(yar_transport_interface_t* self, yar_request_t *request, char **msg) /* {{{ */ { fd_set rfds; zend_string *payload; struct timeval tv; int ret = -1, fd, retval; char buf[SEND_BUF_SIZE]; yar_header_t header = {0}; yar_socket_data_t *data = (yar_socket_data_t *)self->data; FD_ZERO(&rfds); if (SUCCESS == php_stream_cast(data->stream, PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL, (void*)&fd, 1) && fd >= 0) { PHP_SAFE_FD_SET(fd, &rfds); } else { spprintf(msg, 0, "Unable cast socket fd form stream (%s)", strerror(errno)); return 0; } if (!(payload = php_yar_request_pack(request, msg))) { return 0; } DEBUG_C(ZEND_ULONG_FMT": pack request by '%.*s', result len '%ld', content: '%.32s'", request->id, 7, ZSTR_VAL(payload), ZSTR_LEN(payload), ZSTR_VAL(payload) + 8); /* for tcp/unix RPC, we need another way to supports auth */ php_yar_protocol_render(&header, request->id, "Yar PHP Client", NULL, ZSTR_LEN(payload), data->persistent? YAR_PROTOCOL_PERSISTENT : 0); memcpy(buf, (char *)&header, sizeof(yar_header_t)); tv.tv_sec = (ulong)(YAR_G(timeout) / 1000); tv.tv_usec = (ulong)((YAR_G(timeout) % 1000)? (YAR_G(timeout) & 1000) * 1000 : 0); retval = php_select(fd+1, NULL, &rfds, NULL, &tv); if (retval == -1) { zend_string_release(payload); spprintf(msg, 0, "select error '%s'", strerror(errno)); return 0; } else if (retval == 0) { zend_string_release(payload); spprintf(msg, 0, "select timeout '%ld' seconds reached", YAR_G(timeout)); return 0; } if (PHP_SAFE_FD_ISSET(fd, &rfds)) { size_t bytes_left = 0, bytes_sent = 0; if (ZSTR_LEN(payload) > (sizeof(buf) - sizeof(yar_header_t))) { memcpy(buf + sizeof(yar_header_t), ZSTR_VAL(payload), sizeof(buf) - sizeof(yar_header_t)); if ((ret = php_stream_xport_sendto(data->stream, buf, sizeof(buf), 0, NULL, 0)) < 0) { zend_string_release(payload); spprintf(msg, 0, "unable to send data"); return 0; } } else { memcpy(buf + sizeof(yar_header_t), ZSTR_VAL(payload), ZSTR_LEN(payload)); if ((ret = php_stream_xport_sendto(data->stream, buf, sizeof(yar_header_t) + ZSTR_LEN(payload), 0, NULL, 0)) < 0) { zend_string_release(payload); spprintf(msg, 0, "unable to send data"); return 0; } } bytes_sent = ret - sizeof(yar_header_t); bytes_left = ZSTR_LEN(payload) - bytes_sent; wait_io: if (bytes_left) { retval = php_select(fd+1, NULL, &rfds, NULL, &tv); if (retval == -1) { zend_string_release(payload); spprintf(msg, 0, "select error '%s'", strerror(errno)); return 0; } else if (retval == 0) { zend_string_release(payload); spprintf(msg, 0, "select timeout %ldms reached", YAR_G(timeout)); return 0; } if (PHP_SAFE_FD_ISSET(fd, &rfds)) { if ((ret = php_stream_xport_sendto(data->stream, ZSTR_VAL(payload) + bytes_sent, bytes_left, 0, NULL, 0)) > 0) { bytes_left -= ret; bytes_sent += ret; } } goto wait_io; } } zend_string_release(payload); return ret < 0? 0 : 1; } /* }}} */
yar_response_t * php_yar_socket_exec(yar_transport_interface_t* self, yar_request_t *request) /* {{{ */ { fd_set rfds; struct timeval tv; yar_header_t *header; yar_response_t *response; int fd, retval, recvd; size_t len = 0, total_recvd = 0; char *msg, buf[RECV_BUF_SIZE], *payload = NULL; yar_socket_data_t *data = (yar_socket_data_t *)self->data; response = ecalloc(1, sizeof(yar_response_t)); FD_ZERO(&rfds); if (SUCCESS == php_stream_cast(data->stream, PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL, (void*)&fd, 1) && fd >= 0) { PHP_SAFE_FD_SET(fd, &rfds); } else { len = snprintf(buf, sizeof(buf), "Unable cast socket fd form stream (%s)", strerror(errno)); php_yar_response_set_error(response, YAR_ERR_TRANSPORT, buf, len); return response; } tv.tv_sec = (ulong)(YAR_G(timeout) / 1000); tv.tv_usec = (ulong)((YAR_G(timeout) % 1000)? (YAR_G(timeout) & 1000) * 1000 : 0); wait_io: retval = php_select(fd+1, &rfds, NULL, NULL, &tv); if (retval == -1) { len = snprintf(buf, sizeof(buf), "Unable to select %d '%s'", fd, strerror(errno)); php_yar_response_set_error(response, YAR_ERR_TRANSPORT, buf, len); return response; } else if (retval == 0) { len = snprintf(buf, sizeof(buf), "select timeout %ldms reached", YAR_G(timeout)); php_yar_response_set_error(response, YAR_ERR_TRANSPORT, buf, len); return response; } if (PHP_SAFE_FD_ISSET(fd, &rfds)) { zval *retval, rret; if (!payload) { if ((recvd = php_stream_xport_recvfrom(data->stream, buf, sizeof(buf), 0, NULL, NULL, NULL)) > 0) { if (!(header = php_yar_protocol_parse(buf))) { php_yar_error(response, YAR_ERR_PROTOCOL, "malformed response header '%.32s'", payload); return response; } payload = emalloc(header->body_len); len = header->body_len; total_recvd = recvd - sizeof(yar_header_t); memcpy(payload, buf + sizeof(yar_header_t), total_recvd); if (recvd < (sizeof(yar_header_t) + len)) { goto wait_io; } } else if (recvd < 0) { /* this should never happen */ goto wait_io; } } else { if ((recvd = php_stream_xport_recvfrom(data->stream, payload + total_recvd, len - total_recvd, 0, NULL, NULL, NULL)) > 0) { total_recvd += recvd; } if (total_recvd < len) { goto wait_io; } } if (len) { if (!(retval = php_yar_packager_unpack(payload, len, &msg, &rret))) { php_yar_response_set_error(response, YAR_ERR_PACKAGER, msg, strlen(msg)); efree(msg); return response; } php_yar_response_map_retval(response, retval); DEBUG_C(ZEND_ULONG_FMT": server response content packaged by '%.*s', len '%ld', content '%.32s'", response->id, 7, payload, header->body_len, payload + 8); efree(payload); zval_ptr_dtor(retval); } else { php_yar_response_set_error(response, YAR_ERR_EMPTY_RESPONSE, ZEND_STRL("empty response")); } return response; } else { goto wait_io; } } /* }}} */
/* {{{ php_dba_open */ static void php_dba_open(INTERNAL_FUNCTION_PARAMETERS, int persistent) { zval *args = NULL; int ac = ZEND_NUM_ARGS(); dba_mode_t modenr; dba_info *info, *other; dba_handler *hptr; char *key = NULL, *error = NULL; int keylen = 0; int i; int lock_mode, lock_flag, lock_dbf = 0; char *file_mode; char mode[4], *pmode, *lock_file_mode = NULL; int persistent_flag = persistent ? STREAM_OPEN_PERSISTENT : 0; zend_string *opened_path = NULL; char *lock_name; if (ac < 2) { WRONG_PARAM_COUNT; } /* we pass additional args to the respective handler */ args = safe_emalloc(ac, sizeof(zval), 0); if (zend_get_parameters_array_ex(ac, args) != SUCCESS) { efree(args); WRONG_PARAM_COUNT; } /* we only take string arguments */ for (i = 0; i < ac; i++) { if (Z_TYPE(args[i]) != IS_STRING) { convert_to_string_ex(&args[i]); } else if (Z_REFCOUNTED(args[i])) { Z_ADDREF(args[i]); } keylen += Z_STRLEN(args[i]); } if (persistent) { zend_resource *le; /* calculate hash */ key = safe_emalloc(keylen, 1, 1); key[keylen] = '\0'; keylen = 0; for(i = 0; i < ac; i++) { memcpy(key+keylen, Z_STRVAL(args[i]), Z_STRLEN(args[i])); keylen += Z_STRLEN(args[i]); } /* try to find if we already have this link in our persistent list */ if ((le = zend_hash_str_find_ptr(&EG(persistent_list), key, keylen)) != NULL) { FREENOW; if (le->type != le_pdb) { RETURN_FALSE; } info = (dba_info *)le->ptr; GC_REFCOUNT(le)++; RETURN_RES(le); return; } } if (ac==2) { hptr = DBA_G(default_hptr); if (!hptr) { php_error_docref2(NULL, Z_STRVAL(args[0]), Z_STRVAL(args[1]), E_WARNING, "No default handler selected"); FREENOW; RETURN_FALSE; } } else { for (hptr = handler; hptr->name && strcasecmp(hptr->name, Z_STRVAL(args[2])); hptr++); } if (!hptr->name) { php_error_docref2(NULL, Z_STRVAL(args[0]), Z_STRVAL(args[1]), E_WARNING, "No such handler: %s", Z_STRVAL(args[2])); FREENOW; RETURN_FALSE; } /* Check mode: [rwnc][fl]?t? * r: Read * w: Write * n: Create/Truncate * c: Create * * d: force lock on database file * l: force lock on lck file * -: ignore locking * * t: test open database, warning if locked */ strlcpy(mode, Z_STRVAL(args[1]), sizeof(mode)); pmode = &mode[0]; if (pmode[0] && (pmode[1]=='d' || pmode[1]=='l' || pmode[1]=='-')) { /* force lock on db file or lck file or disable locking */ switch (pmode[1]) { case 'd': lock_dbf = 1; if ((hptr->flags & DBA_LOCK_ALL) == 0) { lock_flag = (hptr->flags & DBA_LOCK_ALL); break; } /* no break */ case 'l': lock_flag = DBA_LOCK_ALL; if ((hptr->flags & DBA_LOCK_ALL) == 0) { php_error_docref2(NULL, Z_STRVAL(args[0]), Z_STRVAL(args[1]), E_NOTICE, "Handler %s does locking internally", hptr->name); } break; default: case '-': if ((hptr->flags & DBA_LOCK_ALL) == 0) { php_error_docref2(NULL, Z_STRVAL(args[0]), Z_STRVAL(args[1]), E_WARNING, "Locking cannot be disabled for handler %s", hptr->name); FREENOW; RETURN_FALSE; } lock_flag = 0; break; } } else { lock_flag = (hptr->flags&DBA_LOCK_ALL); lock_dbf = 1; } switch (*pmode++) { case 'r': modenr = DBA_READER; lock_mode = (lock_flag & DBA_LOCK_READER) ? LOCK_SH : 0; file_mode = "r"; break; case 'w': modenr = DBA_WRITER; lock_mode = (lock_flag & DBA_LOCK_WRITER) ? LOCK_EX : 0; file_mode = "r+b"; break; case 'c': modenr = DBA_CREAT; lock_mode = (lock_flag & DBA_LOCK_CREAT) ? LOCK_EX : 0; if (lock_mode) { if (lock_dbf) { /* the create/append check will be done on the lock * when the lib opens the file it is already created */ file_mode = "r+b"; /* read & write, seek 0 */ lock_file_mode = "a+b"; /* append */ } else { file_mode = "a+b"; /* append */ lock_file_mode = "w+b"; /* create/truncate */ } } else { file_mode = "a+b"; } /* In case of the 'a+b' append mode, the handler is responsible * to handle any rewind problems (see flatfile handler). */ break; case 'n': modenr = DBA_TRUNC; lock_mode = (lock_flag & DBA_LOCK_TRUNC) ? LOCK_EX : 0; file_mode = "w+b"; break; default: php_error_docref2(NULL, Z_STRVAL(args[0]), Z_STRVAL(args[1]), E_WARNING, "Illegal DBA mode"); FREENOW; RETURN_FALSE; } if (!lock_file_mode) { lock_file_mode = file_mode; } if (*pmode=='d' || *pmode=='l' || *pmode=='-') { pmode++; /* done already - skip here */ } if (*pmode=='t') { pmode++; if (!lock_flag) { php_error_docref2(NULL, Z_STRVAL(args[0]), Z_STRVAL(args[1]), E_WARNING, "You cannot combine modifiers - (no lock) and t (test lock)"); FREENOW; RETURN_FALSE; } if (!lock_mode) { if ((hptr->flags & DBA_LOCK_ALL) == 0) { php_error_docref2(NULL, Z_STRVAL(args[0]), Z_STRVAL(args[1]), E_WARNING, "Handler %s uses its own locking which doesn't support mode modifier t (test lock)", hptr->name); FREENOW; RETURN_FALSE; } else { php_error_docref2(NULL, Z_STRVAL(args[0]), Z_STRVAL(args[1]), E_WARNING, "Handler %s doesn't uses locking for this mode which makes modifier t (test lock) obsolete", hptr->name); FREENOW; RETURN_FALSE; } } else { lock_mode |= LOCK_NB; /* test =: non blocking */ } } if (*pmode) { php_error_docref2(NULL, Z_STRVAL(args[0]), Z_STRVAL(args[1]), E_WARNING, "Illegal DBA mode"); FREENOW; RETURN_FALSE; } info = pemalloc(sizeof(dba_info), persistent); memset(info, 0, sizeof(dba_info)); info->path = pestrdup(Z_STRVAL(args[0]), persistent); info->mode = modenr; info->argc = ac - 3; info->argv = args + 3; info->flags = (hptr->flags & ~DBA_LOCK_ALL) | (lock_flag & DBA_LOCK_ALL) | (persistent ? DBA_PERSISTENT : 0); info->lock.mode = lock_mode; /* if any open call is a locking call: * check if we already habe a locking call open that should block this call * the problem is some systems would allow read during write */ if (hptr->flags & DBA_LOCK_ALL) { if ((other = php_dba_find(info->path)) != NULL) { if ( ( (lock_mode&LOCK_EX) && (other->lock.mode&(LOCK_EX|LOCK_SH)) ) || ( (other->lock.mode&LOCK_EX) && (lock_mode&(LOCK_EX|LOCK_SH)) ) ) { error = "Unable to establish lock (database file already open)"; /* force failure exit */ } } } if (!error && lock_mode) { if (lock_dbf) { lock_name = Z_STRVAL(args[0]); } else { spprintf(&lock_name, 0, "%s.lck", info->path); if (!strcmp(file_mode, "r")) { /* when in read only mode try to use existing .lck file first */ /* do not log errors for .lck file while in read ony mode on .lck file */ lock_file_mode = "rb"; info->lock.fp = php_stream_open_wrapper(lock_name, lock_file_mode, STREAM_MUST_SEEK|IGNORE_PATH|persistent_flag, &opened_path); } if (!info->lock.fp) { /* when not in read mode or failed to open .lck file read only. now try again in create(write) mode and log errors */ lock_file_mode = "a+b"; } else { if (opened_path) { info->lock.name = pestrndup(opened_path->val, opened_path->len, persistent); zend_string_release(opened_path); } } } if (!info->lock.fp) { info->lock.fp = php_stream_open_wrapper(lock_name, lock_file_mode, STREAM_MUST_SEEK|REPORT_ERRORS|IGNORE_PATH|persistent_flag, &opened_path); if (info->lock.fp) { if (lock_dbf) { /* replace the path info with the real path of the opened file */ pefree(info->path, persistent); info->path = pestrndup(opened_path->val, opened_path->len, persistent); } /* now store the name of the lock */ info->lock.name = pestrndup(opened_path->val, opened_path->len, persistent); zend_string_release(opened_path); } } if (!lock_dbf) { efree(lock_name); } if (!info->lock.fp) { dba_close(info); /* stream operation already wrote an error message */ FREENOW; RETURN_FALSE; } if (!php_stream_supports_lock(info->lock.fp)) { error = "Stream does not support locking"; } if (php_stream_lock(info->lock.fp, lock_mode)) { error = "Unable to establish lock"; /* force failure exit */ } } /* centralised open stream for builtin */ if (!error && (hptr->flags&DBA_STREAM_OPEN)==DBA_STREAM_OPEN) { if (info->lock.fp && lock_dbf) { info->fp = info->lock.fp; /* use the same stream for locking and database access */ } else { info->fp = php_stream_open_wrapper(info->path, file_mode, STREAM_MUST_SEEK|REPORT_ERRORS|IGNORE_PATH|persistent_flag, NULL); } if (!info->fp) { dba_close(info); /* stream operation already wrote an error message */ FREENOW; RETURN_FALSE; } if (hptr->flags & (DBA_NO_APPEND|DBA_CAST_AS_FD)) { /* Needed because some systems do not allow to write to the original * file contents with O_APPEND being set. */ if (SUCCESS != php_stream_cast(info->fp, PHP_STREAM_AS_FD, (void*)&info->fd, 1)) { php_error_docref(NULL, E_WARNING, "Could not cast stream"); dba_close(info); FREENOW; RETURN_FALSE; #ifdef F_SETFL } else if (modenr == DBA_CREAT) { int flags = fcntl(info->fd, F_SETFL); fcntl(info->fd, F_SETFL, flags & ~O_APPEND); #endif } } } if (error || hptr->open(info, &error) != SUCCESS) { dba_close(info); php_error_docref2(NULL, Z_STRVAL(args[0]), Z_STRVAL(args[1]), E_WARNING, "Driver initialization failed for handler: %s%s%s", hptr->name, error?": ":"", error?error:""); FREENOW; RETURN_FALSE; } info->hnd = hptr; info->argc = 0; info->argv = NULL; if (persistent) { zend_resource new_le; new_le.type = le_pdb; new_le.ptr = info; if (zend_hash_str_update_mem(&EG(persistent_list), key, keylen, &new_le, sizeof(zend_resource)) == NULL) { dba_close(info); php_error_docref2(NULL, Z_STRVAL(args[0]), Z_STRVAL(args[1]), E_WARNING, "Could not register persistent resource"); FREENOW; RETURN_FALSE; } } RETVAL_RES(zend_register_resource(info, (persistent ? le_pdb : le_db))); FREENOW; }
int php_imagick_read_image_using_php_streams(php_imagick_object *intern, int type, char *filename, int filename_len TSRMLS_DC) { php_stream *stream; MagickBooleanType status; FILE *fp; #if ZEND_MODULE_API_NO > 20060613 zend_error_handling error_handling; #endif #if ZEND_MODULE_API_NO > 20060613 zend_replace_error_handling(EH_THROW, php_imagick_exception_class_entry, &error_handling TSRMLS_CC); #else php_set_error_handling(EH_THROW, php_imagick_exception_class_entry TSRMLS_CC); #endif stream = php_stream_open_wrapper(filename, "rb", (ENFORCE_SAFE_MODE|IGNORE_PATH) & ~REPORT_ERRORS, NULL); if (!stream) { goto return_error; } if (php_stream_can_cast(stream, PHP_STREAM_AS_STDIO|PHP_STREAM_CAST_INTERNAL) == FAILURE) { goto return_error; } if (php_stream_cast(stream, PHP_STREAM_AS_STDIO|PHP_STREAM_CAST_INTERNAL, (void*)&fp, 0) == FAILURE) { goto return_error; } #if ZEND_MODULE_API_NO > 20060613 zend_restore_error_handling(&error_handling TSRMLS_CC); #else php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC); #endif if (type == 1) { status = MagickReadImageFile(intern->magick_wand, fp); } else { status = MagickPingImageFile(intern->magick_wand, fp); } if (status == MagickFalse) { php_stream_close(stream); return IMAGICK_READ_WRITE_UNDERLYING_LIBRARY; } if (php_stream_is(stream, PHP_STREAM_IS_STDIO)) { char *absolute = expand_filepath(filename, NULL TSRMLS_CC); MagickSetImageFilename(intern->magick_wand, absolute); efree(absolute); } else { /* Set to empty filename, otherwise it will point to MAGICK_TEMP/magick-XXXXX */ MagickSetImageFilename(intern->magick_wand, ""); } php_stream_close(stream); if (status == MagickFalse) { return IMAGICK_READ_WRITE_UNDERLYING_LIBRARY; } IMAGICK_CORRECT_ITERATOR_POSITION(intern); return IMAGICK_READ_WRITE_NO_ERROR; return_error: #if ZEND_MODULE_API_NO > 20060613 zend_restore_error_handling(&error_handling TSRMLS_CC); #else php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC); #endif if (stream) php_stream_close(stream); return IMAGICK_READ_WRITE_UNDERLYING_LIBRARY; }