// Closes a stdio stream after flushing the stream and freeing any buffer // associated with the stream (unless the buffer was set with setbuf). Returns // zero on success; EOF on failure (e.g., if the flush fails, or it is not a // valid fileo or the file is not open, etc.). extern "C" int __cdecl fclose(FILE* const public_stream) { __crt_stdio_stream const stream(public_stream); _VALIDATE_RETURN(stream.valid(), EINVAL, EOF); // If the stream is backed by a string, it requires no synchronization, // flushing, etc., so we can simply free it, which resets all of its // data to the defaults. if (stream.is_string_backed()) { __acrt_stdio_free_stream(stream); return EOF; } int return_value = 0; _lock_file(stream.public_stream()); __try { return_value = _fclose_nolock(stream.public_stream()); } __finally { _unlock_file(stream.public_stream()); } return return_value; }
static VALUE zipruby_archive_read(VALUE self) { VALUE retval = Qnil; struct zipruby_archive *p_archive; FILE *fzip; char buf[DATA_BUFSIZE]; ssize_t n; int block_given; Data_Get_Struct(self, struct zipruby_archive, p_archive); if (NIL_P(p_archive->path)) { rb_raise(rb_eRuntimeError, "invalid Zip::Archive"); } #ifdef _WIN32 if (fopen_s(&fzip, RSTRING_PTR(p_archive->path), "rb") != 0) { rb_raise(Error, "Read archive failed: Cannot open archive"); } #else if ((fzip = fopen(RSTRING_PTR(p_archive->path), "rb")) == NULL) { rb_raise(Error, "Read archive failed: Cannot open archive"); } #endif block_given = rb_block_given_p(); while ((n = fread(buf, 1, sizeof(buf), fzip)) > 0) { if (block_given) { rb_yield(rb_str_new(buf, n)); } else { if (NIL_P(retval)) { retval = rb_str_new(buf, n); } else { rb_str_buf_cat(retval, buf, n); } } } #if defined(RUBY_VM) && defined(_WIN32) _fclose_nolock(fzip); #elif defined(RUBY_WIN32_H) #undef fclose fclose(fzip); #define fclose(f) rb_w32_fclose(f) #else fclose(fzip); #endif if (n == -1) { rb_raise(Error, "Read archive failed"); } return retval; }
errno_t __cdecl _tfreopen_helper( FILE** pfile, const _TSCHAR* filename, const _TSCHAR* mode, FILE* str, int shflag ) { REG1 FILE* stream; _VALIDATE_RETURN_ERRCODE((pfile != NULL), EINVAL); *pfile = NULL; _VALIDATE_RETURN_ERRCODE((filename != NULL), EINVAL); _VALIDATE_RETURN_ERRCODE((mode != NULL), EINVAL); _VALIDATE_RETURN_ERRCODE((str != NULL), EINVAL); /* We deliberately don't hard-validate for emptry strings here. All other invalid path strings are treated as runtime errors by the inner code in _open and openfile. This is also the appropriate treatment here. Since fopen is the primary access point for file strings it might be subjected to direct user input and thus must be robust to that rather than aborting. The CRT and OS do not provide any other path validator (because WIN32 doesn't allow such things to exist in full generality). */ if (*filename == _T('\0')) { errno = EINVAL; return errno; } /* Init stream pointer */ stream = str; _lock_str(stream); __try { /* If the stream is in use, try to close it. Ignore possible * error (ANSI 4.9.5.4). */ if (inuse(stream)) { _fclose_nolock(stream); } stream->_ptr = stream->_base = NULL; stream->_cnt = stream->_flag = 0; #ifdef _UNICODE *pfile = _wopenfile(filename, mode, shflag, stream); #else /* _UNICODE */ *pfile = _openfile(filename, mode, shflag, stream); #endif /* _UNICODE */ } __finally { _unlock_str(stream); } if (*pfile) { return 0; } return errno; }
void file_finalize(JSFreeOp* fop, JSObject* obj) { FileData* fdata = (FileData*)JS_GetPrivate(obj); if (fdata) { free(fdata->path); if (fdata->fptr) { if (fdata->locked) { _unlock_file(fdata->fptr); #if DEBUG fdata->lockLocation = __FILE__; fdata->line = __LINE__; #endif fclose(fdata->fptr); } else _fclose_nolock(fdata->fptr); } delete fdata; } }
void file_finalize(JSContext *cx, JSObject *obj) { FileData* fdata = (FileData*)JS_GetInstancePrivate(cx, obj, &file_class_ex.base, NULL); if(fdata) { free(fdata->path); if(fdata->fptr) { if(fdata->locked) { _unlock_file(fdata->fptr); #if DEBUG fdata->lockLocation = __FILE__; fdata->line = __LINE__; #endif fclose(fdata->fptr); } else _fclose_nolock(fdata->fptr); } delete fdata; } }
static errno_t __cdecl common_freopen( FILE** const result, Character const* const file_name, Character const* const mode, __crt_stdio_stream const stream, int const share_flag ) throw() { typedef __acrt_stdio_char_traits<Character> stdio_traits; _VALIDATE_RETURN_ERRCODE(result != nullptr, EINVAL); *result = nullptr; // C11 7.21.5.4/3: "If filename is a null pointer, the freopen function // attempts to change the mode of the stream to that specified by mode, as // if the name of the file currently associated with the stream had been // used. It is implementation-defined which changes of mode are permitted // (if any), and under what circumstances." // // In our implementation, we do not currently support changing the mode // in this way. In the future, we might consider use of ReOpenFile to // implement support for changing the mode. _VALIDATE_RETURN_ERRCODE_NOEXC(file_name != nullptr, EBADF); _VALIDATE_RETURN_ERRCODE(mode != nullptr, EINVAL); _VALIDATE_RETURN_ERRCODE(stream.valid() , EINVAL); // Just as in the common_fsopen function, we do not hard-validate empty // 'file_name' strings in this function: _VALIDATE_RETURN_ERRCODE_NOEXC(*file_name != 0, EINVAL); errno_t return_value = 0; _lock_file(stream.public_stream()); __try { // If the stream is in use, try to close it, ignoring possible errors: if (stream.is_in_use()) _fclose_nolock(stream.public_stream()); stream->_ptr = nullptr; stream->_base = nullptr; stream->_cnt = 0; stream.unset_flags(-1); // We may have called fclose above, which will deallocate the stream. // We still hold the lock on the stream, though, so we can just reset // the allocated flag to retain ownership. stream.set_flags(_IOALLOCATED); *result = stdio_traits::open_file(file_name, mode, share_flag, stream.public_stream()); if (*result == nullptr) { stream.unset_flags(_IOALLOCATED); return_value = errno; } } __finally { _unlock_file(stream.public_stream()); } return return_value; }