MapHandle::~MapHandle() { if ( munmap( mmap_buf, maplen ) < 0 ) { perror( "munmap" ); throw UnixError( errno ); } }
File::~File() { if ( close( fd ) < 0 ) { perror( "close" ); throw UnixError( errno ); } }
void Exec(const std::string & filePath, char * const argv[], const ForkExecErrorListener & errorListener) { if (::execvp(filePath.c_str(), argv) == -1) { errorListener.OnExecError(filePath, UnixError()); } }
File::File( char *filename ) { /* Open file */ fd = open( filename, O_RDONLY ); if ( fd < 0 ) { perror( "open" ); throw UnixError( errno ); } /* Get size of file */ struct stat thestat; if ( fstat( fd, &thestat ) < 0 ) { perror( "fstat" ); throw UnixError( errno ); } filesize = thestat.st_size; }
const TcpSocket TcpSocket::Create() { int desc = ::socket(PF_INET, SOCK_STREAM, 0); if (desc == -1) { throw UnixError(); } return TcpSocket(desc); }
void DoubleForkExec(const std::string & filePath, const std::vector<std::string> & arguments, const ForkExecErrorListener & errorListener) { pid_t pid = ::fork(); if (pid < 0) { throw UnixError(); } else if (pid != 0) { // Parent process WaitPid(pid); } else { // Child process pid_t pid2 = ::fork(); if (pid2 < 0) { errorListener.OnDoubleForkError(UnixError()); throw ChildExit(); } else if (pid2 != 0) { throw ChildExit(); } else { Exec(filePath, arguments, errorListener); // It will be executed on Exec error. throw ChildExit(); } } }
MapHandle *File::map( off_t offset, size_t len ) { long page = sysconf( _SC_PAGE_SIZE ); off_t mmap_offset = offset & ~(page - 1); uint8_t *mbuf = (uint8_t *)mmap( NULL, len + offset - mmap_offset, PROT_READ, MAP_PRIVATE, fd, mmap_offset ); if ( mbuf == MAP_FAILED ) { perror( "mmap" ); throw UnixError( errno ); } uint8_t *buf = mbuf + offset - mmap_offset; return new MapHandle( buf, mbuf, len + offset - mmap_offset, len ); }
void WaitPid(pid_t pid) { int status = 0; while (true) { pid_t result = ::waitpid(pid, &status, 0); if (result == -1) { if (errno != EINTR) { throw UnixError(); } } else { break; } } }
// @@@ This is a hack for the Network protocol state machine UnixError UnixError::make(int err) { return UnixError(err); }
void UnixError::throwMe(int err) { throw UnixError(err); }