int op_write_native_code(op_agent_t hdl, char const * symbol_name, uint64_t vma, void const * code, unsigned int const size) { struct jr_code_load rec; struct timeval tv; size_t sz_symb_name; char pad_bytes[7] = { 0, 0, 0, 0, 0, 0, 0 }; size_t padding_count; FILE * dumpfile = (FILE *) hdl; if (!dumpfile) { errno = EINVAL; fprintf(stderr, "Invalid hdl argument\n"); return -1; } sz_symb_name = strlen(symbol_name) + 1; rec.id = JIT_CODE_LOAD; rec.code_size = size; rec.vma = vma; rec.code_addr = (u64) (uintptr_t) code; rec.total_size = code ? sizeof(rec) + sz_symb_name + size : sizeof(rec) + sz_symb_name; /* calculate amount of padding '\0' */ padding_count = PADDING_8ALIGNED(rec.total_size); rec.total_size += padding_count; if (gettimeofday(&tv, NULL)) { fprintf(stderr, "gettimeofday failed\n"); return -1; } rec.timestamp = tv.tv_sec; /* locking makes sure that we continuously write this record, if * we are called within a multi-threaded context */ flockfile(dumpfile); /* Write record, symbol name, code (optionally), and (if necessary) * additonal padding \0 bytes. */ if (fwrite_unlocked(&rec, sizeof(rec), 1, dumpfile) && fwrite_unlocked(symbol_name, sz_symb_name, 1, dumpfile)) { if (code) fwrite_unlocked(code, size, 1, dumpfile); if (padding_count) fwrite_unlocked(pad_bytes, padding_count, 1, dumpfile); /* Always flush to ensure conversion code to elf will see * data as soon as possible */ fflush_unlocked(dumpfile); funlockfile(dumpfile); return 0; } fflush_unlocked(dumpfile); funlockfile(dumpfile); return -1; }
int op_write_native_code(op_agent_t hdl, char const * symbol_name, uint64_t vma, void const * code, unsigned int const size) { struct jr_code_load rec; struct timeval tv; size_t sz_symb_name; char pad_bytes[7] = { 0, 0, 0, 0, 0, 0, 0 }; size_t padding_count; FILE * dumpfile = (FILE *) hdl; if (!dumpfile) { errno = EINVAL; fprintf(stderr, "Invalid hdl argument\n"); return -1; } sz_symb_name = strlen(symbol_name) + 1; rec.id = JIT_CODE_LOAD; rec.code_size = size; rec.vma = vma; rec.code_addr = (u64) (uintptr_t) code; rec.total_size = code ? sizeof(rec) + sz_symb_name + size : sizeof(rec) + sz_symb_name; padding_count = PADDING_8ALIGNED(rec.total_size); rec.total_size += padding_count; if (gettimeofday(&tv, NULL)) { fprintf(stderr, "gettimeofday failed\n"); return -1; } rec.timestamp = tv.tv_sec; flockfile(dumpfile); if (fwrite_unlocked(&rec, sizeof(rec), 1, dumpfile) && fwrite_unlocked(symbol_name, sz_symb_name, 1, dumpfile)) { if (code) fwrite_unlocked(code, size, 1, dumpfile); if (padding_count) fwrite_unlocked(pad_bytes, padding_count, 1, dumpfile); fflush_unlocked(dumpfile); funlockfile(dumpfile); return 0; } fflush_unlocked(dumpfile); funlockfile(dumpfile); return -1; }
void vdebug_log (const char *filename, int line, const char *func, const char *format, va_list ap) { static FILE *fp = fopen ("/tmp/tiary_debug.txt", "w"); if (fp) { fprintf_unlocked (fp, "%s:%d:%s:", filename, line, func); vfprintf_unlocked (fp, format, ap); fputc_unlocked ('\n', fp); fflush_unlocked (fp); } }
int fseeko_unlocked(FILE* fp, off_t offset, int whence) { if ( !fp->seek_func ) return errno = EBADF, -1; if ( fflush_unlocked(fp) != 0 ) return -1; if ( fp->seek_func(fp->user, offset, whence) < 0 ) return -1; fp->flags &= ~_FILE_STATUS_EOF; return 0; }
int __fflush4(FILE *stream,int next) { if (__unlikely(!__stdio_atexit)) { __stdio_atexit=1; atexit(__stdio_flushall); } if (__unlikely((stream->flags&BUFINPUT)!=next)) { int res=fflush_unlocked(stream); stream->flags=(stream->flags&~BUFINPUT)|next; return res; } if (stream->fd==0 && __stdin_is_tty()) __fflush_stdout(); return 0; }
size_t fread_unlocked(void *ptr, size_t size, size_t nmemb, FILE *stream) { unsigned long i,j; j=size*nmemb; i=0; if (!(stream->flags&CANREAD)) { stream->flags|=ERRORINDICATOR; return 0; } if (!j || j/nmemb!=size) return 0; if (stream->ungotten) { stream->ungotten=0; *(char*)ptr=stream->ungetbuf; ++i; if (j==1) return 1; } #ifdef WANT_FREAD_OPTIMIZATION if ( !(stream->flags&FDPIPE) && (j>stream->buflen)) { size_t tmp=j-i; ssize_t res; size_t inbuf=stream->bs-stream->bm; memcpy(ptr+i,stream->buf+stream->bm,inbuf); stream->bm=stream->bs=0; tmp-=inbuf; i+=inbuf; if (fflush_unlocked(stream)) return 0; while ((res=__libc_read(stream->fd,ptr+i,tmp))<(ssize_t)tmp) { if (res==-1) { stream->flags|=ERRORINDICATOR; goto exit; } else if (!res) { stream->flags|=EOFINDICATOR; goto exit; } i+=res; tmp-=res; } return nmemb; } #endif for (; i<j; ++i) { int res; res=fgetc_unlocked(stream); if (res==EOF) exit: return i/size; else ((unsigned char*)ptr)[i]=(unsigned char)res; } return nmemb; }
int fputc_unlocked(int c, FILE *stream) { if (!__likely(stream->flags&CANWRITE) || __fflush4(stream,0)) { kaputt: stream->flags|=ERRORINDICATOR; return EOF; } if (__unlikely(stream->bm>=stream->buflen-1)) if (fflush_unlocked(stream)) goto kaputt; if (stream->flags&NOBUF) { #if __BYTE_ORDER == __LITTLE_ENDIAN if (__libc_write(stream->fd,&c,1) != 1) #else if (__libc_write(stream->fd,(char*)&c+sizeof(c)-1,1) != 1) #endif goto kaputt; return 0; } stream->buf[stream->bm]=c; ++stream->bm; if (((stream->flags&BUFLINEWISE) && c=='\n') || ((stream->flags&NOBUF))) /* puke */ if (fflush_unlocked(stream)) goto kaputt; return 0; }
static void inline update_log_file (char *error_buf) { if (! use_log_file) return; if (! log_file_opened) open_log_file (); flockfile (log_file); while (*error_buf != '\0') putc_unlocked (*error_buf++, log_file); putc_unlocked ('\n', log_file); fflush_unlocked (log_file); funlockfile (log_file); }
int op_write_debug_line_info(op_agent_t hdl, void const * code, size_t nr_entry, struct debug_line_info const * compile_map) { struct jr_code_debug_info rec; long cur_pos, last_pos; struct timeval tv; size_t i; size_t padding_count; char padd_bytes[7] = {0, 0, 0, 0, 0, 0, 0}; int rc = -1; FILE * dumpfile = (FILE *) hdl; if (!dumpfile) { errno = EINVAL; fprintf(stderr, "Invalid hdl argument\n"); return -1; } /* write nothing if no entries are provided */ if (nr_entry == 0) return 0; rec.id = JIT_CODE_DEBUG_INFO; rec.code_addr = (uint64_t)(uintptr_t)code; /* will be fixed after writing debug line info */ rec.total_size = 0; rec.nr_entry = nr_entry; if (gettimeofday(&tv, NULL)) { fprintf(stderr, "gettimeofday failed\n"); return -1; } rec.timestamp = tv.tv_sec; flockfile(dumpfile); if ((cur_pos = ftell(dumpfile)) == -1l) goto error; if (!fwrite_unlocked(&rec, sizeof(rec), 1, dumpfile)) goto error; for (i = 0; i < nr_entry; ++i) { if (!fwrite_unlocked(&compile_map[i].vma, sizeof(compile_map[i].vma), 1, dumpfile) || !fwrite_unlocked(&compile_map[i].lineno, sizeof(compile_map[i].lineno), 1, dumpfile) || !fwrite_unlocked(compile_map[i].filename, strlen(compile_map[i].filename) + 1, 1, dumpfile)) goto error; } if ((last_pos = ftell(dumpfile)) == -1l) goto error; rec.total_size = last_pos - cur_pos; padding_count = PADDING_8ALIGNED(rec.total_size); rec.total_size += padding_count; if (padding_count && !fwrite(padd_bytes, padding_count, 1, dumpfile)) goto error; if (fseek(dumpfile, cur_pos, SEEK_SET) == -1l) goto error; if (!fwrite_unlocked(&rec, sizeof(rec), 1, dumpfile)) goto error; if (fseek(dumpfile, last_pos + padding_count, SEEK_SET) == -1) goto error; rc = 0; error: fflush_unlocked(dumpfile); funlockfile(dumpfile); return rc; }
char * getpass (const char *prompt) { FILE *tty; FILE *in, *out; struct termios s, t; bool tty_changed = false; static char *buf; static size_t bufsize; ssize_t nread; /* Try to write to and read from the terminal if we can. If we can't open the terminal, use stderr and stdin. */ tty = fopen ("/dev/tty", "w+"); if (tty == NULL) { in = stdin; out = stderr; } else { /* We do the locking ourselves. */ __fsetlocking (tty, FSETLOCKING_BYCALLER); out = in = tty; } flockfile (out); /* Turn echoing off if it is on now. */ #if HAVE_TCGETATTR if (tcgetattr (fileno (in), &t) == 0) { /* Save the old one. */ s = t; /* Tricky, tricky. */ t.c_lflag &= ~(ECHO | ISIG); tty_changed = (tcsetattr (fileno (in), TCSAFLUSH | TCSASOFT, &t) == 0); } #endif /* Write the prompt. */ fputs_unlocked (prompt, out); fflush_unlocked (out); /* Read the password. */ nread = getline (&buf, &bufsize, in); /* According to the C standard, input may not be followed by output on the same stream without an intervening call to a file positioning function. Suppose in == out; then without this fseek call, on Solaris, HP-UX, AIX, OSF/1, the previous input gets echoed, whereas on IRIX, the following newline is not output as it should be. POSIX imposes similar restrictions if fileno (in) == fileno (out). The POSIX restrictions are tricky and change from POSIX version to POSIX version, so play it safe and invoke fseek even if in != out. */ fseeko (out, 0, SEEK_CUR); if (buf != NULL) { if (nread < 0) buf[0] = '\0'; else if (buf[nread - 1] == '\n') { /* Remove the newline. */ buf[nread - 1] = '\0'; if (tty_changed) { /* Write the newline that was not echoed. */ putc_unlocked ('\n', out); } } } /* Restore the original setting. */ #if HAVE_TCSETATTR if (tty_changed) tcsetattr (fileno (in), TCSAFLUSH | TCSASOFT, &s); #endif funlockfile (out); call_fclose (tty); return buf; }
/** * Internal write API, stream lock already held. * * @returns IPRT status code. * @param pStream The stream. * @param pvBuf What to write. * @param cbWrite How much to write. * @param pcbWritten Where to optionally return the number of bytes * written. * @param fSureIsText Set if we're sure this is UTF-8 text already. */ static int rtStrmWriteLocked(PRTSTREAM pStream, const void *pvBuf, size_t cbWrite, size_t *pcbWritten, bool fSureIsText) { int rc = pStream->i32Error; if (RT_FAILURE(rc)) return rc; if (pStream->fRecheckMode) rtStreamRecheckMode(pStream); #ifdef RT_OS_WINDOWS /* * Use the unicode console API when possible in order to avoid stuff * getting lost in unnecessary code page translations. */ HANDLE hCon; if (rtStrmIsConsoleUnlocked(pStream, &hCon)) { # ifdef HAVE_FWRITE_UNLOCKED if (!fflush_unlocked(pStream->pFile)) # else if (!fflush(pStream->pFile)) # endif { /** @todo Consider buffering later. For now, we'd rather correct output than * fast output. */ DWORD cwcWritten = 0; PRTUTF16 pwszSrc = NULL; size_t cwcSrc = 0; rc = RTStrToUtf16Ex((const char *)pvBuf, cbWrite, &pwszSrc, 0, &cwcSrc); if (RT_SUCCESS(rc)) { if (!WriteConsoleW(hCon, pwszSrc, (DWORD)cwcSrc, &cwcWritten, NULL)) { /* try write char-by-char to avoid heap problem. */ cwcWritten = 0; while (cwcWritten != cwcSrc) { DWORD cwcThis; if (!WriteConsoleW(hCon, &pwszSrc[cwcWritten], 1, &cwcThis, NULL)) { if (!pcbWritten || cwcWritten == 0) rc = RTErrConvertFromErrno(GetLastError()); break; } if (cwcThis != 1) /* Unable to write current char (amount)? */ break; cwcWritten++; } } if (RT_SUCCESS(rc)) { if (cwcWritten == cwcSrc) { if (pcbWritten) *pcbWritten = cbWrite; } else if (pcbWritten) { PCRTUTF16 pwszCur = pwszSrc; const char *pszCur = (const char *)pvBuf; while ((uintptr_t)(pwszCur - pwszSrc) < cwcWritten) { RTUNICP CpIgnored; RTUtf16GetCpEx(&pwszCur, &CpIgnored); RTStrGetCpEx(&pszCur, &CpIgnored); } *pcbWritten = pszCur - (const char *)pvBuf; } else rc = VERR_WRITE_ERROR; } RTUtf16Free(pwszSrc); } } else rc = RTErrConvertFromErrno(errno); if (RT_FAILURE(rc)) ASMAtomicWriteS32(&pStream->i32Error, rc); return rc; } #endif /* RT_OS_WINDOWS */ /* * If we're sure it's text output, convert it from UTF-8 to the current * code page before printing it. * * Note! Partial writes are not supported in this scenario because we * cannot easily report back a written length matching the input. */ /** @todo Skip this if the current code set is UTF-8. */ if ( pStream->fCurrentCodeSet && !pStream->fBinary && ( fSureIsText || rtStrmIsUtf8Text(pvBuf, cbWrite)) ) { char *pszSrcFree = NULL; const char *pszSrc = (const char *)pvBuf; if (pszSrc[cbWrite]) { pszSrc = pszSrcFree = RTStrDupN(pszSrc, cbWrite); if (pszSrc == NULL) rc = VERR_NO_STR_MEMORY; } if (RT_SUCCESS(rc)) { char *pszSrcCurCP; rc = RTStrUtf8ToCurrentCP(&pszSrcCurCP, pszSrc); if (RT_SUCCESS(rc)) { size_t cchSrcCurCP = strlen(pszSrcCurCP); IPRT_ALIGNMENT_CHECKS_DISABLE(); /* glibc / mempcpy again */ #ifdef HAVE_FWRITE_UNLOCKED ssize_t cbWritten = fwrite_unlocked(pszSrcCurCP, cchSrcCurCP, 1, pStream->pFile); #else ssize_t cbWritten = fwrite(pszSrcCurCP, cchSrcCurCP, 1, pStream->pFile); #endif IPRT_ALIGNMENT_CHECKS_ENABLE(); if (cbWritten == 1) { if (pcbWritten) *pcbWritten = cbWrite; } #ifdef HAVE_FWRITE_UNLOCKED else if (!ferror_unlocked(pStream->pFile)) #else else if (!ferror(pStream->pFile)) #endif { if (pcbWritten) *pcbWritten = 0; } else rc = VERR_WRITE_ERROR; RTStrFree(pszSrcCurCP); } RTStrFree(pszSrcFree); } if (RT_FAILURE(rc)) ASMAtomicWriteS32(&pStream->i32Error, rc); return rc; }
void dmn_loggerv(int level, const char* fmt, va_list ap) { if(alt_stderr) { #ifndef NDEBUG time_t t = time(NULL); struct tm tmp; localtime_r(&t, &tmp); char tstamp[10]; if(!strftime(tstamp, 10, "%T ", &tmp)) strcpy(tstamp, "--:--:-- "); # if defined SYS_gettid && !defined __APPLE__ pid_t tid = syscall(SYS_gettid); char tidbuf[16]; snprintf(tidbuf, 16, " [%i]", tid); # endif const char* pfx; switch(level) { case LOG_DEBUG: pfx = pfx_debug; break; case LOG_INFO: pfx = pfx_info; break; case LOG_WARNING: pfx = pfx_warning; break; case LOG_ERR: pfx = pfx_err; break; case LOG_CRIT: pfx = pfx_crit; break; default: pfx = pfx_unknown; break; } flockfile(alt_stderr); fputs_unlocked(tstamp, alt_stderr); if(our_logname) fputs_unlocked(our_logname, alt_stderr); # if defined SYS_gettid && !defined __APPLE__ fputs_unlocked(tidbuf, alt_stderr); # endif fputs_unlocked(pfx, alt_stderr); va_list apcpy; va_copy(apcpy, ap); vfprintf(alt_stderr, fmt, apcpy); va_end(apcpy); putc_unlocked('\n', alt_stderr); fflush_unlocked(alt_stderr); funlockfile(alt_stderr); #else // NDEBUG if(level != LOG_INFO || send_stderr_info) { va_list apcpy; va_copy(apcpy, ap); flockfile(alt_stderr); vfprintf(alt_stderr, fmt, apcpy); va_end(apcpy); putc_unlocked('\n', alt_stderr); fflush_unlocked(alt_stderr); funlockfile(alt_stderr); } #endif // NDEBUG } if(dmn_syslog_alive) vsyslog(level, fmt, ap); dmn_fmtbuf_reset(); }
int fclose(register FILE *stream) { int rv = 0; __STDIO_AUTO_THREADLOCK_VAR; #ifdef __STDIO_HAS_OPENLIST #if !defined(__UCLIBC_HAS_THREADS__) || !defined(__STDIO_BUFFERS) /* First, remove the file from the open file list. */ { FILE *ptr; __STDIO_THREADLOCK_OPENLIST_DEL; __STDIO_THREADLOCK_OPENLIST_ADD; ptr = _stdio_openlist; if ((ptr = _stdio_openlist) == stream) { _stdio_openlist = stream->__nextopen; } else { while (ptr) { if (ptr->__nextopen == stream) { ptr->__nextopen = stream->__nextopen; break; } ptr = ptr->__nextopen; } } __STDIO_THREADUNLOCK_OPENLIST_ADD; __STDIO_THREADUNLOCK_OPENLIST_DEL; } #endif #endif __STDIO_AUTO_THREADLOCK(stream); __STDIO_STREAM_VALIDATE(stream); #ifdef __STDIO_BUFFERS /* Write any pending buffered chars. */ if (__STDIO_STREAM_IS_WRITING(stream)) { rv = fflush_unlocked(stream); } #endif if (__CLOSE(stream) < 0) { /* Must close even if fflush failed. */ rv = EOF; } stream->__filedes = -1; /* We need a way for freopen to know that a file has been closed. * Since a file can't be both readonly and writeonly, that makes * an effective signal. It also has the benefit of disabling * transitions to either reading or writing. */ #if defined(__UCLIBC_HAS_THREADS__) && defined(__STDIO_BUFFERS) /* Before we mark the file as closed, make sure we increment the openlist use count * so it isn't freed under us while still cleaning up. */ __STDIO_OPENLIST_INC_USE; #endif stream->__modeflags &= (__FLAG_FREEBUF|__FLAG_FREEFILE); stream->__modeflags |= (__FLAG_READONLY|__FLAG_WRITEONLY); #ifndef NDEBUG __STDIO_STREAM_RESET_GCS(stream); /* Reinitialize everything (including putc since fflush could fail). */ __STDIO_STREAM_DISABLE_GETC(stream); __STDIO_STREAM_DISABLE_PUTC(stream); __STDIO_STREAM_INIT_BUFREAD_BUFPOS(stream); # ifdef __UCLIBC_HAS_WCHAR__ stream->__ungot_width[0] = 0; # endif # ifdef __STDIO_MBSTATE __INIT_MBSTATE(&(stream->__state)); # endif #endif __STDIO_AUTO_THREADUNLOCK(stream); __STDIO_STREAM_FREE_BUFFER(stream); #ifdef __UCLIBC_MJN3_ONLY__ #warning REMINDER: inefficient - locks and unlocks twice and walks whole list #endif #if defined(__UCLIBC_HAS_THREADS__) && defined(__STDIO_BUFFERS) /* inefficient - locks/unlocks twice and walks whole list */ __STDIO_OPENLIST_INC_DEL_CNT; __STDIO_OPENLIST_DEC_USE; /* This with free the file if necessary. */ #else __STDIO_STREAM_FREE_FILE(stream); #endif return rv; }
size_t fwrite_unlocked(const void *ptr, size_t size, size_t nmemb, FILE *stream) { ssize_t res; size_t len=size*nmemb; size_t i,done; if (!__likely(stream->flags&CANWRITE) || __fflush4(stream,0)) { kaputt: stream->flags|=ERRORINDICATOR; return 0; } if (!nmemb || len/nmemb!=size) return 0; /* check for integer overflow */ if (__unlikely(len>stream->buflen || (stream->flags&NOBUF))) { if (fflush_unlocked(stream)) return 0; do { res=__libc_write(stream->fd,ptr,len); } while (res==-1 && errno==EINTR); } else again: { /* try to make the common case fast */ size_t todo=stream->buflen-stream->bm; if (todo>len) todo=len; if (todo) { if (stream->flags&BUFLINEWISE) { if (__unlikely((stream->flags&CHECKLINEWISE)!=0)) { stream->flags&=~CHECKLINEWISE; /* stdout is set to BUFLINEWISE|CHECKLINEWISE by default. */ /* that means we should check whether it is connected to a * tty on first flush, and if not so, reset BUFLINEWISE */ if (!isatty(stream->fd)) { stream->flags&=~BUFLINEWISE; goto notlinewise; } } for (i=0; i<todo; ++i) { if ((stream->buf[stream->bm++]=((char*)ptr)[i])=='\n') { if (fflush_unlocked(stream)) goto kaputt; } } } else { notlinewise: memcpy(stream->buf+stream->bm,ptr,todo); stream->bm+=todo; if (stream->bm==stream->buflen) { if (fflush_unlocked(stream)) return 0; /* if we are here, we should not have an empty buffer */ len-=todo; if (!len) return nmemb; ptr+=todo; goto again; } else return nmemb; } done=todo; } else done=0; for (i=done; i<len; ++i) if (fputc_unlocked(((char*)ptr)[i],stream) == EOF) { res=len-i; goto abort; } res=len; } if (res<0) { stream->flags|=ERRORINDICATOR; return 0; } abort: return size?res/size:0; }