int _tmain(int argc, _TCHAR* argv[]) { // コンソール出力か? bool useConsole = _isatty(_fileno(stdout)) != 0; // メモリ状況の取得 MEMORYSTATUSEX meminfo = {0}; meminfo.dwLength = sizeof(MEMORYSTATUSEX); if (!GlobalMemoryStatusEx(&meminfo)) { _ftprintf( stderr, _T("GlobalMemoryStatusEx: errorcode: %ld\n"), GetLastError() ); exit(1); } // 物理メモリ使用状況の表示 size_t unit = 1024 * 1024; // 1 MegaBytes _ftprintf( stdout, _T("Phys: %I64d/%I64d MBytes\n"), meminfo.ullAvailPhys / unit, meminfo.ullTotalPhys / unit ); // 最大ループ回数 = 空き物理メモリ(MB単位) size_t maxLoopCount = static_cast<size_t>(meminfo.ullAvailPhys / unit); if (argc > 1) { maxLoopCount = _ttoi(argv[1]); } // 現在のワーキングセットの取得 HANDLE hProcess = GetCurrentProcess(); SIZE_T curMinSize = 0; SIZE_T curMaxSize = 0; GetProcessWorkingSetSize(hProcess, &curMinSize, &curMaxSize); // ワーキングセットの設定 SIZE_T maxMem = (maxLoopCount + 1) * unit + curMaxSize; if (!SetProcessWorkingSetSize( hProcess, maxMem, maxMem)) { _ftprintf( stderr, _T("SetProcessWorkingSetSizeEx: errorcode: %ld\n"), GetLastError() ); // とりあえず継続してみる } // メモリを最大まで確保する. if (maxLoopCount > 0) { std::vector<void *> buf(maxLoopCount); for (size_t loopCount = 0; loopCount < maxLoopCount; loopCount++) { // コンソール出力であればプログレス表示 if (useConsole) { _ftprintf(stderr, _T("allocating... %ld/%ld MBytes \r"), loopCount + 1, maxLoopCount); } // メモリの確保 void *p = VirtualAlloc(NULL, unit, MEM_COMMIT, PAGE_READWRITE); if (p == NULL) { DWORD errcode = GetLastError(); if (useConsole) { _ftprintf(stderr, _T("\n")); } _ftprintf(stderr, _T("VirtualAlloc: errorcode: %ld\n"), errcode); break; } // 確保済みメモリとして記憶する. buf[loopCount] = p; // 物理メモリをロックする if (!VirtualLock(p, unit)) { DWORD errcode = GetLastError(); if (useConsole) { _ftprintf(stderr, _T("\n")); } _ftprintf(stderr, _T("VirtualLock: errorcode: %ld\n"), errcode); break; } } if (useConsole) { _ftprintf(stderr, _T("\n")); } // メモリを解放する for (size_t loopCount = 0; loopCount < maxLoopCount; loopCount++) { void *p = buf[loopCount]; if (p) { VirtualUnlock(p, unit); VirtualFree(p, unit, MEM_DECOMMIT); } } } return 0; }
static DWORD VMCAReadPassword( PCSTR pszUser, PCSTR pszPrompt, PSTR* ppszPassword ) { DWORD dwError = 0; CHAR szPassword[33] = ""; PSTR pszPassword = NULL; DWORD iChar = 0; BOOLEAN bConsole = FALSE; memset(szPassword, 0, sizeof(szPassword)); if (IsNullOrEmptyString(pszPrompt)) { fprintf(stdout, "Enter password for %s: ", pszUser); } else { fprintf(stdout, "%s:", pszPrompt); } fflush(stdout); bConsole = _isatty(0); // Is stdin console? // Read up to 32 characters of password for (; iChar < sizeof(szPassword); iChar++) { CHAR ch = bConsole ? _getch() : getchar(); if (ch == EOF || ch == '\r' || ch == '\n') { fprintf(stdout, "\r\n"); fflush(stdout); break; } else if (ch == '\b') /* backspace */ { if (iChar > 0) { iChar--; szPassword[iChar] = '\0'; } } else { szPassword[iChar] = ch; } } if (IsNullOrEmptyString(szPassword)) { dwError = ERROR_PASSWORD_RESTRICTION; BAIL_ON_VMCA_ERROR(dwError); } dwError = VMCAAllocateStringA(szPassword, &pszPassword); BAIL_ON_VMCA_ERROR(dwError); *ppszPassword = pszPassword; cleanup: return dwError; error: *ppszPassword = NULL; goto cleanup; }
/* now define version that doesn't lock/unlock, validate fh */ int __cdecl _write_nolock ( int fh, const void *buf, unsigned cnt ) { int lfcount; /* count of line feeds */ int charcount; /* count of chars written so far */ int written; /* count of chars written on this write */ ULONG dosretval; /* o.s. return value */ char tmode ; /* textmode - ANSI or UTF-16 */ BOOL toConsole = 0; /* true when writing to console */ BOOL isCLocale = 0; /* true when locale handle is C locale */ lfcount = charcount = 0; /* nothing written yet */ if (cnt == 0) return 0; /* nothing to do */ _VALIDATE_CLEAR_OSSERR_RETURN( (buf != NULL), EINVAL, -1 ); tmode = _textmode(fh); if(tmode == __IOINFO_TM_UTF16LE || tmode == __IOINFO_TM_UTF8) { /* For a UTF-16 file, the count must always be an even number */ _VALIDATE_CLEAR_OSSERR_RETURN(((cnt & 1) == 0), EINVAL, -1); } if (_osfile(fh) & FAPPEND) { /* appending - seek to end of file; ignore error, because maybe file doesn't allow seeking */ #if _INTEGRAL_MAX_BITS >= 64 (void)_lseeki64_nolock(fh, 0, FILE_END); #else /* _INTEGRAL_MAX_BITS >= 64 */ (void)_lseek_nolock(fh, 0, FILE_END); #endif /* _INTEGRAL_MAX_BITS >= 64 */ } /* check for text mode with LF's in the buffer */ /* * Note that in case the handle belongs to Console, write file will * generate garbage output. For user to print these characters * correctly, we will need to print ANSI. * * Also note that in case of printing to Console, we still have to * convert the characters to console codepage. */ if (_isatty(fh) && (_osfile(fh) & FTEXT)) { DWORD dwMode; _ptiddata ptd = _getptd(); isCLocale = (ptd->ptlocinfo->lc_handle[LC_CTYPE] == _CLOCALEHANDLE); toConsole = GetConsoleMode((HANDLE)_osfhnd(fh), &dwMode); } /* don't need double conversion if it's ANSI mode C locale */ if (toConsole && !(isCLocale && (tmode == __IOINFO_TM_ANSI))) { UINT consoleCP = GetConsoleCP(); char mboutbuf[MB_LEN_MAX]; wchar_t tmpchar; int size = 0; int written = 0; char *pch; for (pch = (char *)buf; (unsigned)(pch - (char *)buf) < cnt; ) { BOOL bCR; if (tmode == __IOINFO_TM_ANSI) { bCR = *pch == LF; /* * Here we need to do double convert. i.e. convert from * multibyte to unicode and then from unicode to multibyte in * Console codepage. */ if (!isleadbyte(*pch)) { if (mbtowc(&tmpchar, pch, 1) == -1) { break; } } else if ((cnt - (pch - (char*)buf)) > 1) { if (mbtowc(&tmpchar, pch, 2) == -1) { break; } /* * Increment pch to accomodate DBCS character. */ ++pch; } else { break; } ++pch; } else if (tmode == __IOINFO_TM_UTF8 || tmode == __IOINFO_TM_UTF16LE) { /* * Note that bCR set above is not valid in case of UNICODE * stream. We need to set it using unicode character. */ tmpchar = *(wchar_t *)pch; bCR = tmpchar == LF; pch += 2; } if (tmode == __IOINFO_TM_ANSI) { if( (size = WideCharToMultiByte(consoleCP, 0, &tmpchar, 1, mboutbuf, sizeof(mboutbuf), NULL, NULL)) == 0) { break; } else { if ( WriteFile( (HANDLE)_osfhnd(fh), mboutbuf, size, (LPDWORD)&written, NULL) ) { charcount += written; if (written < size) break; } else { dosretval = GetLastError(); break; } } if (bCR) { size = 1; mboutbuf[0] = CR; if (WriteFile((HANDLE)_osfhnd(fh), mboutbuf, size, (LPDWORD)&written, NULL) ) { if (written < size) break; lfcount ++; charcount++; } else { dosretval = GetLastError(); break; } } } else if ( tmode == __IOINFO_TM_UTF8 || tmode == __IOINFO_TM_UTF16LE) { if ( _putwch_nolock(tmpchar) == tmpchar ) { charcount++; } else { dosretval = GetLastError(); break; } if (bCR) /* emit carriage return */ { size = 1; tmpchar = CR; if ( _putwch_nolock(tmpchar) == tmpchar ) { charcount++; lfcount++; } else { dosretval = GetLastError(); break; } } } } } else if ( _osfile(fh) & FTEXT ) { /* text mode, translate LF's to CR/LF's on output */ dosretval = 0; /* no OS error yet */ if(tmode == __IOINFO_TM_ANSI) { char ch; /* current character */ char *p = NULL, *q = NULL; /* pointers into buf and lfbuf resp. */ char lfbuf[BUF_SIZE]; p = (char *)buf; /* start at beginning of buffer */ while ( (unsigned)(p - (char *)buf) < cnt ) { q = lfbuf; /* start at beginning of lfbuf */ /* fill the lf buf, except maybe last char */ while ( q - lfbuf < sizeof(lfbuf) - 1 && (unsigned)(p - (char *)buf) < cnt ) { ch = *p++; if ( ch == LF ) { ++lfcount; *q++ = CR; } *q++ = ch; } /* write the lf buf and update total */ if ( WriteFile( (HANDLE)_osfhnd(fh), lfbuf, (int)(q - lfbuf), (LPDWORD)&written, NULL) ) { charcount += written; if (written < q - lfbuf) break; } else { dosretval = GetLastError(); break; } } } else if ( tmode == __IOINFO_TM_UTF16LE ){ char lfbuf[BUF_SIZE]; wchar_t wch; /* current wide char */ wchar_t *pu = (wchar_t *)buf; wchar_t *qu = NULL; while ( (unsigned)((char *)pu - (char *)buf) < cnt ) { qu = (wchar_t *)lfbuf; /* start at beginning of lfbuf */ /* fill the lf buf, except maybe last wchar_t */ while ( (((char *)qu - lfbuf) < (sizeof(lfbuf) - 2)) && ((unsigned)((char *)pu - (char *)buf) < cnt )) { wch = *pu++; if ( wch == LF ) { lfcount+=2; *qu++ = CR; } *qu++ = wch; } /* write the lf buf and update total */ if ( WriteFile( (HANDLE)_osfhnd(fh), lfbuf, (int)((char*)qu - lfbuf), (LPDWORD)&written, NULL) ) { charcount += written; if (written < ((char *)qu - lfbuf)) break; } else { dosretval = GetLastError(); break; } } } else { /* * Let's divide the lfbuf in 1:2 wher 1 is for storing * widecharacters and 2 if for converting it to UTF8. This takes * into account the worst case scenario where all the UTF8 * characters are 4 byte long. */ char utf8_buf[(BUF_SIZE*2)/3]; wchar_t utf16_buf[BUF_SIZE/6]; wchar_t wch; /* current wide char */ wchar_t *pu = (wchar_t *)buf; wchar_t *qu = NULL; pu = (wchar_t *)buf; while ((unsigned)((char *)pu - (char *)buf) < cnt) { int bytes_converted = 0; qu = utf16_buf; /* start at beginning of lfbuf */ while ( (((char *)qu - (char *)utf16_buf) < (sizeof(utf16_buf) - 2)) && ((unsigned)((char *)pu - (char *)buf) < cnt )) { wch = *pu++; if ( wch == LF ) { /* no need to count the linefeeds here: we calculate the written chars in another way */ *qu++ = CR; } *qu++ = wch; } bytes_converted = WideCharToMultiByte( CP_UTF8, 0, utf16_buf, ((int)((char *)qu - (char *)utf16_buf))/2, utf8_buf, sizeof(utf8_buf), NULL, NULL); if (bytes_converted == 0) { dosretval = GetLastError(); break; } else { /* * Here we need to make every attempt to write all the * converted characters. The resaon behind this is, * incase half the bytes of a UTF8 character is * written, it may currupt whole of the stream or file. * * The loop below will make sure we exit only if all * the bytes converted are written (which makes sure no * partial MBCS is written) or there was some error in * the stream. */ int bytes_written = 0; do { if (WriteFile( (HANDLE)_osfhnd(fh), utf8_buf + bytes_written, bytes_converted - bytes_written, &written, NULL)) { bytes_written += written; } else { dosretval = GetLastError(); break; } } while ( bytes_converted > bytes_written); /* * Only way the condition below could be true is if * there was en error. In case of error we need to * break this loop as well. */ if (bytes_converted > bytes_written) { break; } /* if this chunk has been committed successfully, update charcount */ charcount = (int)((char *)pu - (char *)buf); } } } } else { /* binary mode, no translation */ if ( WriteFile( (HANDLE)_osfhnd(fh), (LPVOID)buf, cnt, (LPDWORD)&written, NULL) ) { dosretval = 0; charcount = written; } else dosretval = GetLastError(); } if (charcount == 0) { /* If nothing was written, first check if an o.s. error, otherwise we return -1 and set errno to ENOSPC, unless a device and first char was CTRL-Z */ if (dosretval != 0) { /* o.s. error happened, map error */ if (dosretval == ERROR_ACCESS_DENIED) { /* wrong read/write mode should return EBADF, not EACCES */ errno = EBADF; _doserrno = dosretval; } else _dosmaperr(dosretval); return -1; } else if ((_osfile(fh) & FDEV) && *(char *)buf == CTRLZ) return 0; else { errno = ENOSPC; _doserrno = 0; /* no o.s. error */ return -1; } } else /* return adjusted bytes written */ return charcount - lfcount; }
void Logstream::flush(Tee *t) { const size_t MAX_LOG_LINE = 1024 * 10; // this ensures things are sane if ( doneSetup == 1717 ) { string msg = ss.str(); string threadName = getThreadName(); const char * type = logLevelToString(logLevel); size_t msgLen = msg.size(); if ( msgLen > MAX_LOG_LINE ) msgLen = MAX_LOG_LINE; const int spaceNeeded = (int)( msgLen + 64 /* for extra info */ + threadName.size()); int bufSize = 128; while ( bufSize < spaceNeeded ) bufSize += 128; BufBuilder b(bufSize); char* dateStr = b.grow(24); curTimeString(dateStr); dateStr[23] = ' '; // change null char to space if (!threadName.empty()) { b.appendChar( '[' ); b.appendStr( threadName , false ); b.appendChar( ']' ); b.appendChar( ' ' ); } for ( int i=0; i<indent; i++ ) b.appendChar( '\t' ); if ( type[0] ) { b.appendStr( type , false ); b.appendStr( ": " , false ); } if ( msg.size() > MAX_LOG_LINE ) { stringstream sss; sss << "warning: log line attempted (" << msg.size() / 1024 << "k) over max size(" << MAX_LOG_LINE / 1024 << "k)"; sss << ", printing beginning and end ... "; b.appendStr( sss.str(), false ); const char * xx = msg.c_str(); b.appendBuf( xx , MAX_LOG_LINE / 3 ); b.appendStr( " .......... ", false ); b.appendStr( xx + msg.size() - ( MAX_LOG_LINE / 3 ) ); } else { b.appendStr( msg ); } string out( b.buf() , b.len() - 1); verify( b.len() < spaceNeeded ); scoped_lock lk(mutex); if( t ) t->write(logLevel,out); if ( globalTees ) { for ( unsigned i=0; i<globalTees->size(); i++ ) (*globalTees)[i]->write(logLevel,out); } #if defined(_WIN32) int fd = fileno( logfile ); if ( _isatty( fd ) ) { fflush( logfile ); writeUtf8ToWindowsConsole( out.data(), out.size() ); } #else if ( isSyslog ) { syslog( logLevelToSysLogLevel(logLevel) , "%s" , out.data() ); } #endif else if ( fwrite( out.data(), out.size(), 1, logfile ) ) { fflush(logfile); } else { int x = errno; cout << "Failed to write to logfile: " << errnoWithDescription(x) << ": " << out << endl; } #ifdef POSIX_FADV_DONTNEED // This only applies to pages that have already been flushed RARELY posix_fadvise(fileno(logfile), 0, 0, POSIX_FADV_DONTNEED); #endif } _init(); }
isatty (int fildes) { return _isatty (fildes); }
/* putc() with code conversion */ int putc2(int c, FILE *fp) { static int num[NOFILE]; /* 0 : not in Kanji 1..4 : in JIS Kanji and num[] bytes are in store[][] -1 : in JIS Kanji and store[][] is empty */ static unsigned char store[NOFILE][4]; const int fd = fileno(fp); int ret = c, output_enc; #ifdef WIN32 if ((fp == stdout || fp == stderr) && (_isatty(fd) || !prior_file_enc)) { if (sjisterminal) { if (is_internalUPTEX()) output_enc = ENC_UTF8; else output_enc = ENC_SJIS; } else #else if ((fp == stdout || fp == stderr) && !prior_file_enc) { #endif output_enc = get_terminal_enc(); } else output_enc = get_file_enc(); if (num[fd] > 0) { /* multi-byte char */ if (is_internalUPTEX() && iskanji1(c)) { /* error */ ret = flush(store[fd], num[fd], fp); num[fd] = 0; } store[fd][num[fd]] = c; num[fd]++; if (multistrlen(store[fd], num[fd], 0) == num[fd]) { long i = fromBUFF(store[fd], num[fd], 0); ret = put_multibyte(toENC(i, output_enc), fp); num[fd] = -1; } else if ((is_internalUPTEX() && num[fd] == 4) || (!is_internalUPTEX() && num[fd] == 2)) { /* error */ ret = flush(store[fd], num[fd], fp); num[fd] = -1; } } else if (iskanji1(c)) { /* first multi-byte char */ if (num[fd] == 0 && output_enc == ENC_JIS) { ret = put_multibyte(KANJI_IN, fp); } store[fd][0] = c; num[fd] = 1; } else { /* ASCII */ if (num[fd] < 0 && output_enc == ENC_JIS) { put_multibyte(KANJI_OUT, fp); } ret = putc(c, fp); num[fd] = 0; } return ret; } /* fputs() with code conversion */ int fputs2(const char *s, FILE *fp) { while (*s != '\0') { int ret = putc2((unsigned char)*s, fp); if (ret == EOF) return EOF; s++; } return 1; } static struct unget_st { int size; int buff[4]; } ungetbuff[NOFILE]; static int getc4(FILE *fp) { struct unget_st *p = &ungetbuff[fileno(fp)]; if (p->size == 0) return getc(fp); return p->buff[--p->size]; } static int ungetc4(int c, FILE *fp) { struct unget_st *p = &ungetbuff[fileno(fp)]; if (p->size >= 4) return EOF; return p->buff[p->size++] = c; } static unsigned char *buffer; static long first, last; static boolean combin_voiced_sound(boolean semi) { int i; if (last-2 < first) return false; if (multistrlen(buffer,last,last-2) != 2) return false; i = toUCS(fromBUFF(buffer,last,last-2)); i = get_voiced_sound(i, semi); if (i == 0) return false; i = toBUFF(fromUCS(i)); buffer[last-2] = HI(i); buffer[last-1] = LO(i); return true; }
int __cdecl _flswbuf ( int ch, FILE *str ) #endif /* _UNICODE */ { FILE *stream; int charcount; int written; int fh; _ASSERTE(str != NULL); stream = str; fh = _fileno(stream); if (!(stream->_flag & (_IOWRT|_IORW))) { errno = EBADF; stream->_flag |= _IOERR; return(_TEOF); } else if ((stream->_flag & _IOSTRG)) { errno = ERANGE; stream->_flag |= _IOERR; return(_TEOF); } /* Check that _IOREAD is not set or, if it is, then so is _IOEOF. Note that _IOREAD and IOEOF both being set implies switching from read to write at end-of-file, which is allowed by ANSI. Note that resetting the _cnt and _ptr fields amounts to doing an fflush() on the stream in this case. Note also that the _cnt field has to be reset to 0 for the error path as well (i.e., _IOREAD set but _IOEOF not set) as well as the non-error path. */ if (stream->_flag & _IOREAD) { stream->_cnt = 0; if (stream->_flag & _IOEOF) { stream->_ptr = stream->_base; stream->_flag &= ~_IOREAD; } else { stream->_flag |= _IOERR; return(_TEOF); } } stream->_flag |= _IOWRT; stream->_flag &= ~_IOEOF; written = charcount = stream->_cnt = 0; /* Get a buffer for this stream, if necessary. */ if (!anybuf(stream)) { /* Do NOT get a buffer if (1) stream is stdout/stderr, and (2) stream is NOT a tty. [If stdout/stderr is a tty, we do NOT set up single char buffering. This is so that later temporary buffering will not be thwarted by the _IONBF bit being set (see _stbuf/_ftbuf usage).] */ if (!( ((stream==stdout) || (stream==stderr)) && (_isatty(fh)) )) _getbuf(stream); } /* end !anybuf() */ /* If big buffer is assigned to stream... */ if (bigbuf(stream)) { _ASSERTE(("inconsistent IOB fields", stream->_ptr - stream->_base >= 0)); charcount = (int)(stream->_ptr - stream->_base); stream->_ptr = stream->_base + sizeof(TCHAR); stream->_cnt = stream->_bufsiz - (int)sizeof(TCHAR); if (charcount > 0) written = _write(fh, stream->_base, charcount); else if (_osfile_safe(fh) & FAPPEND) { if( _lseeki64(fh,0L,SEEK_END)==-1) { stream->_flag |= _IOERR; return(_TEOF); } } #ifndef _UNICODE *stream->_base = (char)ch; #else /* _UNICODE */ *(wchar_t *)(stream->_base) = (wchar_t)(ch & 0xffff); #endif /* _UNICODE */ } /* Perform single character output (either _IONBF or no buffering) */ else { charcount = sizeof(TCHAR); #ifndef _UNICODE written = _write(fh, &ch, charcount); #else /* _UNICODE */ { char mbc[4]; *(wchar_t *)mbc = (wchar_t)(ch & 0xffff); written = _write(fh, mbc, charcount); } #endif /* _UNICODE */ } /* See if the _write() was successful. */ if (written != charcount) { stream->_flag |= _IOERR; return(_TEOF); } #ifndef _UNICODE return(ch & 0xff); #else /* _UNICODE */ return(ch & 0xffff); #endif /* _UNICODE */ }
int main(int argc, char **argv) #endif { LPTSTR tail; #ifdef WGP_CONSOLE HINSTANCE hInstance = GetModuleHandle(NULL), hPrevInstance = NULL; #else int i; #endif #ifndef WGP_CONSOLE # if defined( __MINGW32__) && !defined(_W64) # define argc _argc # define argv _argv # else /* MSVC, WATCOM, MINGW-W64 */ # define argc __argc # define argv __argv # endif #endif /* WGP_CONSOLE */ szModuleName = (LPTSTR) malloc((MAXSTR + 1) * sizeof(TCHAR)); CheckMemory(szModuleName); /* get path to gnuplot executable */ GetModuleFileName(hInstance, szModuleName, MAXSTR); if ((tail = _tcsrchr(szModuleName, '\\')) != NULL) { tail++; *tail = 0; } szModuleName = (LPTSTR) realloc(szModuleName, (_tcslen(szModuleName) + 1) * sizeof(TCHAR)); CheckMemory(szModuleName); if (_tcslen(szModuleName) >= 5 && _tcsnicmp(&szModuleName[_tcslen(szModuleName)-5], TEXT("\\bin\\"), 5) == 0) { size_t len = _tcslen(szModuleName) - 4; szPackageDir = (LPTSTR) malloc((len + 1) * sizeof(TCHAR)); CheckMemory(szPackageDir); _tcsncpy(szPackageDir, szModuleName, len); szPackageDir[len] = NUL; } else { szPackageDir = szModuleName; } #ifndef WGP_CONSOLE textwin.hInstance = hInstance; textwin.hPrevInstance = hPrevInstance; textwin.nCmdShow = nCmdShow; textwin.Title = L"gnuplot"; #endif /* create structure of first graph window */ graphwin = (LPGW) calloc(1, sizeof(GW)); listgraphs = graphwin; /* locate ini file */ { char * inifile; #ifdef UNICODE LPWSTR winifile; #endif get_user_env(); /* this hasn't been called yet */ inifile = gp_strdup("~\\wgnuplot.ini"); gp_expand_tilde(&inifile); /* if tilde expansion fails use current directory as default - that was the previous default behaviour */ if (inifile[0] == '~') { free(inifile); inifile = "wgnuplot.ini"; } #ifdef UNICODE graphwin->IniFile = winifile = UnicodeText(inifile, S_ENC_DEFAULT); #else graphwin->IniFile = inifile; #endif #ifndef WGP_CONSOLE textwin.IniFile = graphwin->IniFile; #endif ReadMainIni(graphwin->IniFile, TEXT("WGNUPLOT")); } #ifndef WGP_CONSOLE textwin.IniSection = TEXT("WGNUPLOT"); textwin.DragPre = L"load '"; textwin.DragPost = L"'\n"; textwin.lpmw = &menuwin; textwin.ScreenSize.x = 80; textwin.ScreenSize.y = 80; textwin.KeyBufSize = 2048; textwin.CursorFlag = 1; /* scroll to cursor after \n & \r */ textwin.shutdown = MakeProcInstance((FARPROC)ShutDown, hInstance); textwin.AboutText = (LPTSTR) malloc(1024 * sizeof(TCHAR)); CheckMemory(textwin.AboutText); wsprintf(textwin.AboutText, TEXT("Version %hs patchlevel %hs\n") \ TEXT("last modified %hs\n") \ TEXT("%hs\n%hs, %hs and many others\n") \ TEXT("gnuplot home: http://www.gnuplot.info\n"), gnuplot_version, gnuplot_patchlevel, gnuplot_date, gnuplot_copyright, authors[1], authors[0]); textwin.AboutText = (LPTSTR) realloc(textwin.AboutText, (_tcslen(textwin.AboutText) + 1) * sizeof(TCHAR)); CheckMemory(textwin.AboutText); menuwin.szMenuName = szMenuName; #endif pausewin.hInstance = hInstance; pausewin.hPrevInstance = hPrevInstance; pausewin.Title = L"gnuplot pause"; graphwin->hInstance = hInstance; graphwin->hPrevInstance = hPrevInstance; #ifdef WGP_CONSOLE graphwin->lptw = NULL; #else graphwin->lptw = &textwin; #endif /* init common controls */ { INITCOMMONCONTROLSEX initCtrls; initCtrls.dwSize = sizeof(INITCOMMONCONTROLSEX); initCtrls.dwICC = ICC_WIN95_CLASSES; InitCommonControlsEx(&initCtrls); } #ifndef WGP_CONSOLE if (TextInit(&textwin)) gp_exit(EXIT_FAILURE); textwin.hIcon = LoadIcon(hInstance, TEXT("TEXTICON")); SetClassLongPtr(textwin.hWndParent, GCLP_HICON, (LONG_PTR)textwin.hIcon); /* Note: we want to know whether this is an interactive session so that we can * decide whether or not to write status information to stderr. The old test * for this was to see if (argc > 1) but the addition of optional command line * switches broke this. What we really wanted to know was whether any of the * command line arguments are file names or an explicit in-line "-e command". * (This is a copy of a code snippet from plot.c) */ for (i = 1; i < argc; i++) { if (!_stricmp(argv[i], "/noend")) continue; if ((argv[i][0] != '-') || (argv[i][1] == 'e')) { interactive = FALSE; break; } } if (interactive) ShowWindow(textwin.hWndParent, textwin.nCmdShow); if (IsIconic(textwin.hWndParent)) { /* update icon */ RECT rect; GetClientRect(textwin.hWndParent, (LPRECT) &rect); InvalidateRect(textwin.hWndParent, (LPRECT) &rect, 1); UpdateWindow(textwin.hWndParent); } # ifndef __WATCOMC__ /* Finally, also redirect C++ standard output streams. */ RedirectOutputStreams(TRUE); # endif #else /* !WGP_CONSOLE */ # ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING # define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004 # endif { /* Enable Windows 10 Console Virtual Terminal Sequences */ HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); DWORD mode; GetConsoleMode(handle, &mode); SetConsoleMode(handle, mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING); } #endif gp_atexit(WinExit); if (!_isatty(_fileno(stdin))) _setmode(_fileno(stdin), O_BINARY); gnu_main(argc, argv); /* First chance to close help system for console gnuplot, second for wgnuplot */ WinCloseHelp(); gp_exit_cleanup(); return 0; }
int __flushbuf(int c, FILE * stream) { _clean = __cleanup; if (fileno(stream) < 0) return EOF; if (!io_testflag(stream, _IOWRITE)) return EOF; if (io_testflag(stream, _IOREADING) && !feof(stream)) return EOF; stream->_flags &= ~_IOREADING; stream->_flags |= _IOWRITING; if (!io_testflag(stream, _IONBF)) { if (!stream->_buf) { if (stream == stdout && _isatty(fileno(stdout))) { if (!(stream->_buf = (unsigned char *) malloc(BUFSIZ))) { stream->_flags |= _IONBF; } else { stream->_flags |= _IOLBF|_IOMYBUF; stream->_bufsiz = BUFSIZ; stream->_count = -1; } } else { if (!(stream->_buf = (unsigned char *) malloc(BUFSIZ))) { stream->_flags |= _IONBF; } else { stream->_flags |= _IOMYBUF; stream->_bufsiz = BUFSIZ; if (!io_testflag(stream, _IOLBF)) stream->_count = BUFSIZ - 1; else stream->_count = -1; } } stream->_ptr = stream->_buf; } } if (io_testflag(stream, _IONBF)) { char c1 = c; stream->_count = 0; if (io_testflag(stream, _IOAPPEND)) { if (_lseek(fileno(stream), 0L, SEEK_END) == -1) { stream->_flags |= _IOERR; return EOF; } } if (_write(fileno(stream), &c1, 1) != 1) { stream->_flags |= _IOERR; return EOF; } return c; } else if (io_testflag(stream, _IOLBF)) { *stream->_ptr++ = c; if (c == '\n' || stream->_count == -stream->_bufsiz) { if (io_testflag(stream, _IOAPPEND)) { if (_lseek(fileno(stream), 0L, SEEK_END) == -1) { stream->_flags |= _IOERR; return EOF; } } if (! do_write(fileno(stream), (char *)stream->_buf, -stream->_count)) { stream->_flags |= _IOERR; return EOF; } else { stream->_ptr = stream->_buf; stream->_count = 0; } } } else { int count = stream->_ptr - stream->_buf; stream->_count = stream->_bufsiz - 1; stream->_ptr = stream->_buf + 1; if (count > 0) { if (io_testflag(stream, _IOAPPEND)) { if (_lseek(fileno(stream), 0L, SEEK_END) == -1) { stream->_flags |= _IOERR; return EOF; } } if (! do_write(fileno(stream), (char *)stream->_buf, count)) { *(stream->_buf) = c; stream->_flags |= _IOERR; return EOF; } } *(stream->_buf) = c; } return c; }
void initialise_output() { if (_isatty(_fileno(stdout))) _setmode(_fileno(stdout), _O_U16TEXT); if (_isatty(_fileno(stderr))) _setmode(_fileno(stderr), _O_U16TEXT); }
int posix_isatty(int fd) { return _isatty(fd); }
void std_logger::out(exlib::string& txt) { #ifdef _WIN32 class color_out { public: color_out() { m_handle = GetStdHandle(STD_OUTPUT_HANDLE); m_Now = m_wAttr = 0x7; m_wLight = m_wAttr & FOREGROUND_INTENSITY; } void out(exlib::string& s) { exlib::wstring ws = utf8to16String(s); exlib::wchar *ptr = &ws[0]; exlib::wchar *pend = ptr + ws.length(); exlib::wchar *ptr2; DWORD dwWrite; while (ptr2 = (exlib::wchar *) qstrchr(ptr, L'\x1b')) { if (ptr2[1] == '[') { WriteConsoleW(m_handle, ptr, (DWORD)(ptr2 - ptr), &dwWrite, NULL); ptr2 += 2; while (true) { if (ptr2[0] == 'm') { m_Now = m_wAttr; m_wLight = m_wAttr & FOREGROUND_INTENSITY; SetConsoleTextAttribute(m_handle, m_Now); ptr2 ++; break; } if (qisdigit(ptr2[0])) { if (ptr2[1] == 'm') { if (ptr2[0] == '0') { m_Now = m_wAttr; m_wLight = m_wAttr & FOREGROUND_INTENSITY; SetConsoleTextAttribute(m_handle, m_Now); } ptr2 += 2; break; } WORD mask, val; WORD light = m_wLight; if (ptr2[1] == ';') { if (ptr2[0] == '0') m_wLight = light = 0; else if (ptr2[0] == '1') m_wLight = light = FOREGROUND_INTENSITY; ptr2 += 2; } if (ptr2[0] == '3') { mask = 0xf0; ptr2 ++; } else if (ptr2[0] == '4') { mask = 0x0f; ptr2 ++; } else if (ptr2[0] == '9') { mask = 0xf0; light |= FOREGROUND_INTENSITY; ptr2 ++; } else if (ptr2[0] == '1' && ptr2[1] == '0') { mask = 0x0f; light |= FOREGROUND_INTENSITY << 4; ptr2 += 2; } else break; if (!qisdigit(ptr2[0])) break; val = ptr2[0] - '0'; if (val != 8) { if (val == 9) { val = (m_wAttr & 0x0f) | (m_Now & 0xf0); m_Now = val | light; SetConsoleTextAttribute(m_handle, m_Now); } else { val = (val & 2) | ((val & 1) ? 4 : 0) | ((val & 4) ? 1 : 0); if (mask == 0x0f) val <<= 4; m_Now = (m_Now & mask) | val | light; SetConsoleTextAttribute(m_handle, m_Now); } } ptr2 ++; if (ptr2[0] == 'm') { ptr2 ++; break; } } } } ptr = ptr2; } WriteConsoleW(m_handle, ptr, (DWORD)(pend - ptr), &dwWrite, NULL); } private: HANDLE m_handle; WORD m_wAttr, m_Now; WORD m_wLight; }; static color_out s_out; if (_isatty(_fileno(stdout))) s_out.out(txt); else #endif { fwrite(txt.c_str(), 1, txt.length(), stdout); fflush(stdout); } }
APR_DECLARE(apr_status_t) apr_file_dup2(apr_file_t *new_file, apr_file_t *old_file, apr_pool_t *p) { #ifdef _WIN32_WCE return APR_ENOTIMPL; #else HANDLE hproc = GetCurrentProcess(); HANDLE newhand = NULL; apr_int32_t newflags; int fd; if (new_file->flags & APR_STD_FLAGS) { if ((new_file->flags & APR_STD_FLAGS) == APR_STDERR_FLAG) { /* Flush stderr and unset its buffer, then commit the fd-based buffer. * This is typically a noop for Win2K/XP since services with NULL std * handles [but valid FILE *'s, oddly enough], but is required * for NT 4.0 and to use this code outside of services. */ fflush(stderr); setvbuf(stderr, NULL, _IONBF, 0); if (!_isatty(2)) { _commit(2 /* stderr */); } /* Clone a handle can _close() without harming the source handle, * open an MSVCRT-based pseudo-fd for the file handle, then dup2 * and close our temporary pseudo-fd once it's been duplicated. * This will incidently keep the FILE-based stderr in sync. * Note the apparently redundant _O_BINARY coersions are required. * Note the _dup2 will close the previous std Win32 handle. */ if (!DuplicateHandle(hproc, old_file->filehand, hproc, &newhand, 0, FALSE, DUPLICATE_SAME_ACCESS)) { return apr_get_os_error(); } fd = _open_osfhandle((INT_PTR)newhand, _O_WRONLY | _O_BINARY); _dup2(fd, 2); _close(fd); _setmode(2, _O_BINARY); /* hPipeWrite was _close()'ed above, and _dup2()'ed * to fd 2 creating a new, inherited Win32 handle. * Recover that real handle from fd 2. Note that * SetStdHandle(STD_ERROR_HANDLE, _get_osfhandle(2)) * is implicit in the dup2() call above */ newhand = (HANDLE)_get_osfhandle(2); } else if ((new_file->flags & APR_STD_FLAGS) == APR_STDOUT_FLAG) { /* For the process flow see the stderr case above */ fflush(stdout); setvbuf(stdout, NULL, _IONBF, 0); if (!_isatty(1)) { _commit(1 /* stdout */); } if (!DuplicateHandle(hproc, old_file->filehand, hproc, &newhand, 0, FALSE, DUPLICATE_SAME_ACCESS)) { return apr_get_os_error(); } fd = _open_osfhandle((INT_PTR)newhand, _O_WRONLY | _O_BINARY); _dup2(fd, 1); _close(fd); _setmode(1, _O_BINARY); newhand = (HANDLE)_get_osfhandle(1); } else if ((new_file->flags & APR_STD_FLAGS) == APR_STDIN_FLAG) { /* For the process flow see the stderr case above */ fflush(stdin); setvbuf(stdin, NULL, _IONBF, 0); if (!DuplicateHandle(hproc, old_file->filehand, hproc, &newhand, 0, FALSE, DUPLICATE_SAME_ACCESS)) { return apr_get_os_error(); } fd = _open_osfhandle((INT_PTR)newhand, _O_RDONLY | _O_BINARY); _dup2(fd, 0); _close(fd); _setmode(0, _O_BINARY); newhand = (HANDLE)_get_osfhandle(0); } newflags = (new_file->flags & APR_STD_FLAGS) | (old_file->flags & ~APR_STD_FLAGS) | APR_INHERIT; /* No need to close the old file, _dup2() above did that for us */ } else { if (!DuplicateHandle(hproc, old_file->filehand, hproc, &newhand, 0, FALSE, DUPLICATE_SAME_ACCESS)) { return apr_get_os_error(); } newflags = old_file->flags & ~(APR_STD_FLAGS | APR_INHERIT); if (new_file->filehand && (new_file->filehand != INVALID_HANDLE_VALUE)) { CloseHandle(new_file->filehand); } } new_file->flags = newflags; new_file->filehand = newhand; new_file->fname = apr_pstrdup(new_file->pool, old_file->fname); new_file->append = old_file->append; new_file->buffered = FALSE; new_file->ungetchar = old_file->ungetchar; #if APR_HAS_THREADS if (old_file->mutex) { apr_thread_mutex_create(&(new_file->mutex), APR_THREAD_MUTEX_DEFAULT, p); } #endif return APR_SUCCESS; #endif /* !defined(_WIN32_WCE) */ }
// edit or display a file with vertical & horizontal scrolling & text searching int _near List_Cmd( LPTSTR pszCmdLine ) { int nFVal, nReturn = 0, argc; TCHAR szSource[MAXFILENAME+1], szFileName[MAXFILENAME+1], *pszArg; FILESEARCH dir; memset( &dir, '\0', sizeof(FILESEARCH) ); // check for and remove switches if ( GetRange( pszCmdLine, &(dir.aRanges), 0 ) != 0 ) return ERROR_EXIT; // check for /T"search string" GetMultiCharSwitch( pszCmdLine, _TEXT("T"), szSource, 255 ); if ( szSource[0] == _TEXT('"') ) sscanf( szSource+1, _TEXT("%79[^\"]"), szListFindWhat ); else if ( szSource[0] ) sprintf( szListFindWhat, FMT_PREC_STR, 79, szSource ); if ( GetSwitches( pszCmdLine, _TEXT("*HIRSWX"), &lListFlags, 0 ) != 0 ) return ( Usage( LIST_USAGE )); if ( szSource[0] ) lListFlags |= LIST_SEARCH; // check for pipe to LIST w/o explicit /S switch if ( first_arg( pszCmdLine ) == NULL ) { if ( _isatty( STDIN ) == 0 ) lListFlags |= LIST_STDIN; else if (( lListFlags & LIST_STDIN ) == 0 ) return ( Usage( LIST_USAGE )); } // initialize buffers & globals if ( ListInit() ) return ERROR_EXIT; nCurrent = nStart = 0; // ^C handling if ( setjmp( cv.env ) == -1 ) { list_abort: FindClose( dir.hdir ); Cls_Cmd( NULL ); nReturn = CTRLC; goto list_bye; } RestartFileSearch: for ( argc = 0; ; argc++ ) { // break if at end of arg list, & not listing STDIN if (( pszArg = ntharg( pszCmdLine, argc )) == NULL ) { if (( lListFlags & LIST_STDIN ) == 0 ) break; } else strcpy( szSource, pszArg ); for ( nFVal = FIND_FIRST; ; ) { szClip[0] = _TEXT('\0'); // if not reading from STDIN, get the next matching file if (( lListFlags & LIST_STDIN ) == 0 ) { // qualify filename if ( nFVal == FIND_FIRST ) { mkfname( szSource, 0 ); if ( is_dir( szSource )) mkdirname( szSource, WILD_FILE ); } if ( stricmp( szSource, CLIP ) == 0 ) { RedirToClip( szClip, 99 ); if ( CopyFromClipboard( szClip ) != 0 ) break; strcpy( szFileName, szClip ); } else if ( QueryIsPipeName( szSource )) { // only look for pipe once if ( nFVal == FIND_NEXT ) break; copy_filename( szFileName, szSource ); } else if ( find_file( nFVal, szSource, ( FIND_BYATTS | FIND_RANGE | FIND_EXCLUDE | 0x07), &dir, szFileName ) == NULL ) { nReturn = (( nFVal == FIND_FIRST ) ? ERROR_EXIT : 0 ); break; } else if ( nStart < nCurrent ) { nStart++; nFVal = FIND_NEXT; continue; } else if ( dir.ulSize > 0L ) LFile.lSize = dir.ulSize; } // clear the screen (scrolling the buffer first to save the current screen) Cls_Cmd( NULL ); if (( nReturn = _list( szFileName )) == CTRLC ) goto list_abort; if ( szClip[0] ) remove( szClip ); if ( nReturn != 0 ) break; SetCurPos( nScreenRows, 0 ); if (( szClip[0] ) || ( lListFlags & LIST_STDIN )) break; if ( LFile.hHandle > 0 ) _close( LFile.hHandle ); LFile.hHandle = -1; // increment index to current file if ( nCurrent < nStart ) { FindClose( dir.hdir ); nStart = 0; goto RestartFileSearch; } else { nFVal = FIND_NEXT; nCurrent++; nStart++; } } // we can only read STDIN once! lListFlags &= ~LIST_STDIN; } crlf(); list_bye: FreeMem( LFile.lpBufferStart ); if ( LFile.hHandle > 0 ) _close( LFile.hHandle ); LFile.hHandle = -1; return nReturn; }
int QLuaApplication::Private::processArguments(int argc, char **argv) { bool has_e = false; bool has_v = false; bool stdinmode = false; // Obtain and lock lua QtLuaLocker lua(theEngine); globalL = lua; // Good time to limit access to QtLuaConsole lua_pushcfunction(lua, hook_qluaconsole); luaQ_pushmeta(lua, &QLuaConsole::staticMetaObject); lua_call(lua, 1, 0); // parse lua argument int argn = 1; int status; while (argn < argc) { const char *a; const char *s = argv[argn]; if (s[0] != '-') break; if (s[1] == 0) break; argn += 1; if (s[1] == '-' && s[2] == 0) break; switch(s[1]) { case '-': if (s[2]) return printBadOption(s); break; case 'i': if (!strcmp(s, "-ide") || !strncmp(s, "-ide=", 5)) break; else if (s[2]) return printBadOption(s); interactive = ttyConsole = true; theConsole->setCtrlCHandler(QLuaConsole::ctrlCBreak); theConsole->setPrintCapturedOutput(true); break; case 'v': if (s[2]) return printBadOption(s); has_v = true; break; case 'e': has_e = true; a = s + 2; if (a[0]==0 && argn < argc) a = argv[argn++]; lua.setRunning(); if (a && a[0]) if ((status = doString(lua, a))) return status; break; case 'l': a = s + 2; if (a[0]==0 && argn < argc) a = argv[argn++]; lua.setRunning(); if (a && a[0]) if ((status = doLibrary(lua, a))) return status; break; case 'h': if (s[2]) return printBadOption(s); return printUsage(); break; case 'n': case 'o': default: if (strcmp(s, "-nographics") && strcmp(s, "-onethread") ) return printBadOption(s); break; } } // script mode? if (argn>=argc && !has_e && !has_v) { int c = EOF; #if HAVE_ISATTY bool stdin_is_tty = isatty(0); #elif defined(WIN32) bool stdin_is_tty = _isatty(_fileno(stdin)); #else bool stdin_is_tty = true; #endif if (stdin_is_tty) interactive = ttyConsole = true; else if ((c = fgetc(stdin)) != EOF) stdinmode = true; if (stdinmode) ungetc(c, stdin); } // handle script if (argn < argc) if ((status = doScript(lua, argc, argv, argn))) return status; // handle stdin if (stdinmode) if ((status = doScript(lua, argc, argv, argc))) return status; // run interactive if there are toplevel windows foreach(QWidget *w, QApplication::topLevelWidgets()) if (w && w->isVisible() && w->windowType() != Qt::Desktop) interactive = true; // do we need to print the version? forceVersion = has_v; if (has_v && !interactive) printLuaVersion(); return 0; }
main(int argc,char *argv[]) #endif { int listener_fd, new_fd; int remotelen; int port = 0; int c, on; struct sockaddr_in local_sin, remote_sin; static fd_set fdset, fdset_saved; struct conn_stat *rconn, *wconn; #ifdef STE_WINDOWS u_long param = 0; /* FIONBIO コマンドのパラメータ Non-Blocking ON*/ int nRtn; WSADATA wsaData; stehubstat_t stehubstat[1]; nRtn = WSAStartup(MAKEWORD(1, 1), &wsaData); #endif while ((c = getopt(argc, argv, "p:d:")) != EOF){ switch (c) { case 'p': port = atoi(optarg); break; case 'd': debuglevel = atoi(optarg); break; default: print_usage(argv[0]); } } conn_stat_head->next = NULL; conn_stat_head->fd = 0; if(( listener_fd = socket( AF_INET, SOCK_STREAM,0 )) < 0 ) { SET_ERRNO(); print_err(LOG_ERR,"socket: %s (%d)\n", strerror(errno), errno); exit(1); } on = 1; if((setsockopt(listener_fd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on))) <0){ SET_ERRNO(); print_err(LOG_ERR,"setsockopt:%s\n", strerror(errno)); exit(1); } if(port == 0) port = PORT_NO; memset((char *)&remote_sin, 0x0, sizeof(struct sockaddr_in)); memset((char *)&local_sin, 0x0, sizeof(struct sockaddr_in)); local_sin.sin_port = htons((short)port); local_sin.sin_family = AF_INET; local_sin.sin_addr.s_addr = htonl(INADDR_ANY); if(bind(listener_fd,(struct sockaddr *)&local_sin,sizeof(struct sockaddr_in)) < 0 ){ SET_ERRNO(); print_err(LOG_ERR,"bind:%s\n", strerror(errno)); exit(1); } /* * accept() でブロックされるのを防ぐため、non-blocking mode に設定 */ #ifndef STE_WINDOWS if( fcntl (listener_fd, F_SETFL, O_NONBLOCK) < 0) { #else if( ioctlsocket(listener_fd, FIONBIO, ¶m) < 0){ #endif SET_ERRNO(); print_err(LOG_ERR, "Failed to set nonblock: %s (%d)\n",strerror(errno), errno); exit(1); } if(listen(listener_fd, 5) < 0) { SET_ERRNO(); print_err(LOG_ERR,"listen:%s\n", strerror(errno)); exit(1); } FD_ZERO(&fdset_saved); FD_SET(listener_fd, &fdset_saved); /* * syslog のための設定。Facility は LOG_USER とする * Windows の場合はログファイルをオープンする。 */ #ifdef STE_WINDOWS hStedLog = CreateFile(STEHUB_LOG_FILE, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ| FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); SetFilePointer(hStedLog, 0, NULL, FILE_END); if(isTerminal == FALSE){ /* サービスとして呼ばれている(コマンドプロンプトから呼ばれていない)場合 */ stehubServiceStatus.dwServiceType = SERVICE_WIN32; stehubServiceStatus.dwCurrentState = SERVICE_START_PENDING; stehubServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; stehubServiceStatus.dwWin32ExitCode = 0; stehubServiceStatus.dwServiceSpecificExitCode = 0; stehubServiceStatus.dwCheckPoint = 0; stehubServiceStatus.dwWaitHint = 0; /* サービスコントロールハンドラーを登録 */ stehubServiceStatusHandle = RegisterServiceCtrlHandlerEx( "Stehub", //LPCTSTR stehub_svc_ctrl_handler, //LPHANDLER_FUNCTION_EX (LPVOID)stehubstat //LPVOID ); if (stehubServiceStatusHandle == (SERVICE_STATUS_HANDLE)0){ return; } stehubServiceStatus.dwCurrentState = SERVICE_RUNNING; stehubServiceStatus.dwCheckPoint = 0; stehubServiceStatus.dwWaitHint = 0; if (!SetServiceStatus (stehubServiceStatusHandle, &stehubServiceStatus)){ // SetServiceStatus が失敗した場合の処理・・ print_err(LOG_ERR, "SetServiceStatus Failed\n"); } } #else openlog(basename(argv[0]),LOG_PID,LOG_USER); #endif /* * ここまではとりあえず、フォアグラウンドで実行。 * ここからは、デバッグレベル 0 (デフォルト)なら、バックグラウンド * で実行し、そうでなければフォアグラウンド続行。 * Windows の場合は、いづれにしてもフォアグラウンドで実行 * し、デバッグレベル 1 以上の場合はログをファイルに書く。 */ if (debuglevel == 0){ #ifndef STE_WINDOWS print_err(LOG_NOTICE,"Going to background mode\n"); if(become_daemon() != 0){ print_err(LOG_ERR,"can't become daemon\n"); print_err(LOG_ERR,"Exit\n"); exit(1); } #else use_log = 1; #endif } print_err(LOG_NOTICE,"Started\n"); /* * メインループ * 仮想 NIC デーモンからの接続要求を待ち、接続後は仮想 NIC デーモン * からのデータを待つ。1つの仮想デーモンからのデータを他方に転送する。 */ for(;;){ fdset = fdset_saved; if( select(FD_SETSIZE, &fdset, NULL, NULL, NULL) < 0){ SET_ERRNO(); print_err(LOG_ERR,"select:%s\n", strerror(errno)); } if(FD_ISSET(listener_fd, &fdset)){ remotelen = sizeof(struct sockaddr_in); if((new_fd = accept(listener_fd,(struct sockaddr *)&remote_sin, &remotelen)) < 0){ SET_ERRNO(); if(errno == EINTR || errno == EWOULDBLOCK || errno == ECONNABORTED){ print_err(LOG_NOTICE, "accept: %s\n", strerror(errno)); continue; } else { print_err(LOG_ERR, "accept: %s\n", strerror(errno)); return(-1); } } FD_SET(new_fd, &fdset_saved); print_err(LOG_NOTICE,"fd%d: connection from %s\n",new_fd, inet_ntoa(remote_sin.sin_addr)); add_conn_stat(new_fd, remote_sin.sin_addr); /* * recv() でブロックされるのを防ぐため、non-blocking mode に設定 */ #ifndef STE_WINDOWS if (fcntl(new_fd, F_SETFL, O_NONBLOCK) < 0 ) { #else if(ioctlsocket(new_fd, FIONBIO, ¶m) < 0){ #endif SET_ERRNO(); print_err(LOG_ERR, "fd%d: Failed to set nonblock: %s (%d)\n", new_fd,strerror(errno),errno); return(-1); } continue; } for( rconn = conn_stat_head->next ; rconn != NULL ; rconn = rconn->next){ int rfd, wfd; rfd = rconn->fd; if (FD_ISSET(rfd, &fdset)){ int rsize; char databuf[SOCKBUFSIZE]; char *bufp; int datalen; bufp = (char *)databuf; rsize = recv(rfd, bufp, SOCKBUFSIZE,0); if(rsize == 0){ /* * コネクションが切断されたようだ。 * socket を close してループを抜ける */ print_err(LOG_ERR,"fd%d: Connection closed by %s\n", rfd, inet_ntoa(rconn->addr)); CLOSE(rfd); print_err(LOG_ERR,"fd%d: closed\n", rfd); FD_CLR(rfd, &fdset_saved); delete_conn_stat(rfd); break; } if(rsize < 0){ SET_ERRNO(); /* * 致命的でない error の場合は無視してループを継続 */ if(errno == EINTR || errno == EWOULDBLOCK){ print_err(LOG_NOTICE, "fd%d: recv: %s\n", rfd, strerror(errno)); continue; } /* * エラーが発生したようだ。 * socket を close して forループを抜ける */ print_err(LOG_ERR,"fd%d: recv: %s\n", rfd,strerror(errno)); CLOSE(rfd); print_err(LOG_ERR,"fd%d: closed\n", rfd); FD_CLR(rfd, &fdset_saved); delete_conn_stat(rfd); break; } /* * 他の仮想 NIC にパケットを転送する。 * 「待ち」が発生すると、パフォーマンスに影響があるので、EWOULDBLOCK * の場合は配送をあきらめる。 */ for(wconn = conn_stat_head->next ; wconn != NULL ; wconn = wconn->next){ wfd = wconn->fd; if (rfd == wfd) continue; if( debuglevel > 1){ print_err(LOG_ERR,"fd%d(%s) ==> ", rfd, inet_ntoa(rconn->addr)); print_err(LOG_ERR,"fd%d(%s)\n", wfd,inet_ntoa(wconn->addr)); } if ( send(wfd, bufp, rsize, 0) < 0){ SET_ERRNO(); if(errno == EINTR || errno == EWOULDBLOCK ){ print_err(LOG_NOTICE,"fd%d: send: %s\n", wfd ,strerror(errno)); continue; } else { print_err(LOG_ERR,"fd%d: send: %s (%d)\n",wfd,strerror(errno), errno); CLOSE(wfd); print_err(LOG_ERR,"fd%d: closed\n", wfd); FD_CLR(wfd, &fdset_saved); delete_conn_stat(wfd); break; } } } /* End of loop for send()ing */ } } /* End of loop for each connection */ } /* End of main loop */ } #ifdef STE_WINDOWS /************************************************************************** * Windows の場合の main() * * 引数が -I もしくは -U だった場合には本プログラム(仮想 HUB デーモン) * を Windows のサービスとして登録/登録解除する。 * それ以外の引数が渡された場合には ste_svc_main() を直接呼び出し、引数も * そのまま ste_svc_main() に渡す。 * * 引数(argvとして): * * -I : サービスとして登録。 * -U : 登録解除 * **************************************************************************/ int WINAPIV main(int argc, char *argv[]) { int c; SERVICE_TABLE_ENTRY DispatchTable[] = { { "Stehub", stehub_svc_main}, { NULL, NULL } }; isTerminal = _isatty(_fileno(stdout))? TRUE:FALSE; // // 引数が無ない場合。 // コマンドプロンプトから呼ばれた時は stehub_svc_main() を呼び、 // そうでなければ StartServiceCtlDispatcher() を呼ぶ。 // if(argc == 1 ){ if(isTerminal == TRUE){ stehub_svc_main(argc, argv); return(0); } else { StartServiceCtrlDispatcher(DispatchTable); return(0); } } while((c = getopt(argc, argv, "IU")) != EOF ){ switch(c){ case 'I': // stehub.exe をサービスとして登録 if(stehub_install_svc()) printf("Service Installed Sucessfully\n"); else printf("Error Installing Service\n"); break; case 'U': // stehub.exe のサービスとして登録を解除 if(stehub_delete_svc()) printf("Service UnInstalled Sucessfully\n"); else printf("Error UnInstalling Service\n"); break; default : // // 引数が -U、-I でなければコマンドプロンプト内で // stehub.exe を起動したいのだと判断し、引数を全て // stehub_svc_main() に渡して呼び出す。 // stehub_svc_main(argc, argv); return(0); } } return(0); } /**************************************** * Windows サービス登録ルーチン * ****************************************/ BOOL stehub_install_svc() { LPCTSTR lpszBinaryPathName; TCHAR strDir[1024]; HANDLE schSCManager,schService; GetCurrentDirectory(1024, strDir); strcat((char *)strDir, "\\stehub.exe"); schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS); if (schSCManager == NULL) return FALSE; lpszBinaryPathName=strDir; schService = CreateService(schSCManager,"Stehub", "Stehub Virtual HUB daemon", // 表示用サービス名 SERVICE_ALL_ACCESS, // アクセス SERVICE_WIN32_OWN_PROCESS, // サービスタイプ SERVICE_DEMAND_START, // スタートタイプ SERVICE_ERROR_NORMAL, // エラーコントロールタイプ lpszBinaryPathName, // バイナリへのパス NULL, // No load ordering group NULL, // No tag identifier NULL, // No dependencies NULL, // LocalSystem account NULL);// No password if (schService == NULL) return FALSE; CloseServiceHandle(schService); return TRUE; } /**************************************** * Windows サービス登録解除ルーチン * ****************************************/ BOOL stehub_delete_svc() { HANDLE schSCManager; SC_HANDLE hService; schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS); if (schSCManager == NULL) return FALSE; hService=OpenService(schSCManager, "Stehub", SERVICE_ALL_ACCESS); if (hService == NULL) return FALSE; if(DeleteService(hService)==0) return FALSE; if(CloseServiceHandle(hService)==0) return FALSE; return TRUE; } /****************************************************************************** * stehub_svc_ctrl_handler() * * サービスステータスハンドラー * DEVICEEVENT を拾うためには Handler ではなく、HandlerEx じゃないといけないらしい。 * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/handlerex.asp * * まったく呼ばれていないような・・? ******************************************************************************/ DWORD WINAPI stehub_svc_ctrl_handler( DWORD dwControl, DWORD dwEventType, LPVOID lpEventData, LPVOID lpContext ) { PDEV_BROADCAST_HDR p = (PDEV_BROADCAST_HDR) lpEventData; WPARAM wParam = (WPARAM) dwEventType; stehubstat_t *stehubstat = NULL; stehubstat = (stehubstat_t *)lpContext; if(debuglevel > 1){ print_err(LOG_DEBUG, "Service Status Handler stehub_svc_ctrl_handler called\n"); } switch(dwControl){ case SERVICE_CONTROL_DEVICEEVENT: break; case SERVICE_CONTROL_PAUSE: stehubServiceStatus.dwCurrentState = SERVICE_PAUSED; break; case SERVICE_CONTROL_CONTINUE: stehubServiceStatus.dwCurrentState = SERVICE_RUNNING; break; case SERVICE_CONTROL_STOP: stehubServiceStatus.dwWin32ExitCode = 0; stehubServiceStatus.dwCurrentState = SERVICE_STOPPED; stehubServiceStatus.dwCheckPoint = 0; stehubServiceStatus.dwWaitHint = 0; SetServiceStatus (stehubServiceStatusHandle,&stehubServiceStatus); break; case SERVICE_CONTROL_INTERROGATE: break; } return NO_ERROR; }
int readwrite(SOCKET fd) { fd_set fdr1; unsigned char buffer[1024]; int istty,ct1,ct2; struct timeval timer; memset(buffer,0,sizeof(buffer)); istty=_isatty(0); timer.tv_sec=0; timer.tv_usec=0; while(1) { FD_ZERO(&fdr1); FD_SET(fd,&fdr1); ct1=select(0,&fdr1,NULL,NULL,&timer); if(ct1==SOCKET_ERROR) { printf("[-] select error:%d\n",GetLastError()); break; } if(FD_ISSET(fd,&fdr1)) { ct1=recv(fd,buffer,sizeof(buffer)-1,0); if((ct1==SOCKET_ERROR) || (ct1==0)) { printf("[-] target maybe close the socket.\n"); break; } if(_write(1,buffer,ct1)<=0) { printf("[-] write to stdout error:%d\n",GetLastError()); break; } memset(buffer,0,sizeof(buffer)); } if(istty) { if(_kbhit()) /* stdin can read */ { ct1=read(0,buffer,sizeof(buffer)-1); if(ct1 <= 0) { printf("[-] read from stdin error:%d\n",GetLastError()); break; } ct2=send(fd,buffer,ct1,0); if((ct2==SOCKET_ERROR) || (ct2==0)) { printf("[-] target maybe close the socket.\n"); break; } if( strnicmp(buffer, "exit", 4) == 0) { printf("[+] Connection closed in exit command.\n"); break; } memset(buffer,0,sizeof(buffer)); } } else { ct1=read(0,buffer,sizeof(buffer)-1); if(ct1<=0) { printf("[-] read from nontty stdin error:%d\n",GetLastError()); break; } ct2=send(fd,buffer,ct1,0); if((ct2==SOCKET_ERROR) || (ct2==0)) { printf("[-] target maybe close the socket\n"); break; } if( strnicmp(buffer, "exit", 4) == 0) { printf("[+] Connection closed in exit command.\n"); break; } memset(buffer,0,sizeof(buffer)); } } return(1); }
int __gsh_is_console (int fd) { return _isatty (fd); }