#include #include #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef HAVE_UNISTD_H #include #else #include #endif #include #include "Output.h" #include "Exceptions.h" #include "gettext.h" #ifndef S_ISREG #define S_ISREG(x) 1 #endif Output::Output(String no, int create, int trunc) throw (GeneralException) : Handle(no.strlen() ? wrapopen(no.to_charp(), create, trunc) : dup(1)), n(no) { if (GetHandle() < 0) { throw IOGeneral(String(_("Error opening file ")) + no + _(" for writing: ") + strerror(errno)); } size = lseek(GetHandle(), 0, SEEK_END); lseek(GetHandle(), 0, SEEK_SET); struct stat s; fstat(GetHandle(), &s); date_modif = s.st_mtime; } int Output::wrapopen(const String & n, int create, int trunc) { #ifndef _WIN32 return open(n.to_charp(), (create ? O_CREAT : 0) | (trunc ? O_TRUNC : 0) | O_WRONLY, 00666); #else DWORD dwCreationDisposition; switch ((create ? 1 : 0) | (trunc ? 2 : 0)) { case 0: // no creation, no trunc dwCreationDisposition = OPEN_EXISTING; break; case 1: // creation, no trunc if existing dwCreationDisposition = OPEN_ALWAYS; break; case 2: // no creation, trunc of existing file dwCreationDisposition = TRUNCATE_EXISTING; break; case 3: // creation, truc if existing dwCreationDisposition = CREATE_ALWAYS; break; } hFile = CreateFile( n.to_charp(), GENERIC_WRITE, FILE_SHARE_READ, 0, dwCreationDisposition, FILE_ATTRIBUTE_ARCHIVE, 0); return _open_osfhandle((INT_PTR) hFile, O_WRONLY | O_BINARY); #endif } Output::Output(const Output & o) : Handle(o), n(o.n) { } bool Output::CanWrite() const { return 1; } bool Output::CanRead() const { return 0; } bool Output::CanSeek() const { struct stat s; fstat(GetHandle(), &s); return S_ISREG(s.st_mode); } off_t Output::seek(off_t offset, int whence) throw (GeneralException) { if ((itell = lseek(GetHandle(), offset, whence)) < 0) { throw IOGeneral(String(_("Error seeking file ")) + n + _(": ") + strerror(errno)); } #ifdef PARANOID_SEEK if (itell != lseek(GetHandle(), 0, SEEK_CUR)) { throw IOGeneral(String(_("Error seeking file ")) + n + _(": the position does not match")); } #endif return itell; } String Output::GetName() const { return n; } Stdout_t::Stdout_t() {} bool Stdout_t::CanSeek() const { return 0; } String Stdout_t::GetName() const { return "Stdout"; } Stderr_t::Stderr_t() : Handle(dup(2)) {} bool Stderr_t::CanWrite() const { return 1; } bool Stderr_t::CanRead() const { return 0; } bool Stderr_t::CanSeek() const { return 0; } String Stderr_t::GetName() const { return "Stderr"; } #ifdef HOOK_STDS Stdout_t Stdout; Stderr_t Stderr; #endif