diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/BLua.cc | 38 | ||||
-rw-r--r-- | lib/CopyJob.cc | 14 | ||||
-rw-r--r-- | lib/Handle.cc | 36 | ||||
-rw-r--r-- | lib/LuaHandle.cc | 11 | ||||
-rw-r--r-- | lib/Socket.cc | 53 | ||||
-rw-r--r-- | lib/String.cc | 32 | ||||
-rw-r--r-- | lib/Task.cc | 2 | ||||
-rw-r--r-- | lib/TaskMan.cc | 120 |
8 files changed, 270 insertions, 36 deletions
diff --git a/lib/BLua.cc b/lib/BLua.cc index 14ab466..58aef96 100644 --- a/lib/BLua.cc +++ b/lib/BLua.cc @@ -1,6 +1,6 @@ /* * Baltisot - * Copyright (C) 1999-2003 Nicolas "Pixel" Noble + * Copyright (C) 1999-2006 Nicolas "Pixel" Noble * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* $Id: BLua.cc,v 1.33 2005-12-01 14:29:20 pixel Exp $ */ +/* $Id: BLua.cc,v 1.34 2006-01-31 17:02:39 pixel Exp $ */ #include <stdlib.h> #include "BLua.h" @@ -73,6 +73,8 @@ class LuaStatics : public Base { static int getglobal(lua_State *); static int dumpvars(lua_State *); + + static int iconv(lua_State *); }; std::map<lua_State *, Lua *> Lua::lualist; @@ -267,6 +269,26 @@ int LuaStatics::dumpvars(lua_State * _L) { return 0; } +int LuaStatics::iconv(lua_State * _L) { + Lua * L = Lua::find(_L); + int n = L->gettop(); + String str, from, to; + + if ((n != 3) || !L->isstring(1) || !L->isstring(2) || !L->isstring(3)) { + L->error("Incorrect arguments to function `string.iconv'"); + } + + str = L->tostring(1); + from = L->tostring(2); + to = L->tostring(3); + + str.iconv(from, to); + + L->push(str); + + return 1; +} + Lua::Lua() : L(lua_open()) { lualist[L] = this; lua_atpanic(L, LuaStatics::luapanic); @@ -318,6 +340,9 @@ void Lua::open_io() { void Lua::open_string() { luaopen_string(L); + push("iconv"); + push(LuaStatics::iconv); + settable(); lua_pop(L, 1); } @@ -589,6 +614,11 @@ int LuaStatics::putF(lua_State * L, const void * p, size_t size, void * ud) { return lf->f->write(p, size) == size; } +String Lua::escape_string(const String & s) { + /* TODO */ + return s; +} + void Lua::load(Handle * h, bool docall) throw (GeneralException) { LoadF lf; int status; @@ -662,7 +692,7 @@ void Lua::dumpvars_r(Handle * h, int i, int depth) throw (GeneralException) { t = String("[") + (lua_toboolean(L, -2) ? "true" : "false") + "] = "; break; case LUA_TSTRING: - t = lua_tostring(L, -2) + String(" = "); + t = "[\"" + escape_string(lua_tostring(L, -2)) + String("\"] = "); break; case LUA_TTABLE: t = "-- [a table]\n"; @@ -703,7 +733,7 @@ void Lua::dumpvars_r(Handle * h, int i, int depth) throw (GeneralException) { (*h) << (lua_toboolean(L, -1) ? "true" : "false") << ",\n"; break; case LUA_TSTRING: - (*h) << "\"" << lua_tostring(L, -1) << "\",\n"; + (*h) << "\"" << escape_string(lua_tostring(L, -1)) << "\",\n"; break; case LUA_TTABLE: (*h) << "{\n"; diff --git a/lib/CopyJob.cc b/lib/CopyJob.cc index fc2a0ca..9f7da95 100644 --- a/lib/CopyJob.cc +++ b/lib/CopyJob.cc @@ -5,15 +5,16 @@ #include "gettext.h" CopyJob::CopyJob(Handle * as, Handle * ad, ssize_t asiz, bool ads, bool add, int ashape) : s(as), d(ad), ds(ads), dd(add), siz(asiz), cursiz(0), r(0), w(0), tw(0), shape(ashape) { - struct timezone tz; - s->SetNonBlock(); d->SetNonBlock(); WaitFor(s, W4_READING); - +#ifndef _WIN32 + struct timezone tz; + if (shape > 0) { gettimeofday(&start, &tz); } +#endif } CopyJob::~CopyJob() { @@ -29,12 +30,15 @@ CopyJob::~CopyJob() { int CopyJob::Do() throw (GeneralException) { int tr; struct timeval now; - struct timezone tz; +#ifndef _WIN32 + struct timezone tz; + if (shape > 0) { gettimeofday(&now, &tz); } - +#endif + switch (current) { case 0: tr = siz >= 0 ? siz - cursiz : COPY_BUFSIZ; diff --git a/lib/Handle.cc b/lib/Handle.cc index 684001d..4722e94 100644 --- a/lib/Handle.cc +++ b/lib/Handle.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* $Id: Handle.cc,v 1.75 2005-02-17 08:33:50 pixel Exp $ */ +/* $Id: Handle.cc,v 1.76 2006-01-31 17:02:39 pixel Exp $ */ #include <stdio.h> #include <string.h> @@ -62,7 +62,7 @@ enum { INFLATE }; -Handle::Handle(const Handle & nh) : itell(0), hFile(0), h(nh.h >= 0 ? dup(nh.h) : nh.h), closed(nh.closed), nonblock(nh.closed), zfile(0), z(0), hMapObject(0), mapped(0) +Handle::Handle(const Handle & nh) : itell(0), hFile(0), h(nh.h >= 0 ? nh.ndup() : nh.h), closed(nh.closed), nonblock(nh.closed), zfile(0), z(0), hMapObject(0), mapped(0) { #ifdef DEBUG printm(M_INFO, String(_("Duplication of handle ")) + nh.h + _(" to ") + h + "\n"); @@ -79,7 +79,7 @@ Handle::~Handle() { close(); } -Handle::Handle(int nh) : h(nh), closed(false), nonblock(false), zfile(0), z(0), hMapObject(0), mapped(0) +Handle::Handle(int nh) : itell(0), h(nh), closed(false), nonblock(false), zfile(0), z(0), hMapObject(0), mapped(0) { #ifdef DEBUG printm(M_INFO, String(_("Initialising handle ")) + h + "\n"); @@ -210,7 +210,7 @@ Handle & operator<<(Handle & h, const String & s) { const char * p; p = s.to_charp(); - h.write(p, strlen(p)); + h.write(p, s.strlen()); return h; } @@ -259,7 +259,7 @@ void Handle::close() throw (GeneralException) { throw GeneralException(String(_("Error during inflateEnd: ")) + zstrm.msg); } } - err = ::close(h); + err = nclose(); if (err) { throw GeneralException(String(_("Error during (zstream) close: ")) + strerror(errno)); } @@ -279,12 +279,16 @@ void Handle::close() throw (GeneralException) { } } } else { +#ifndef NO_HFILE if (!hFile) { - int err = ::close(h); +#endif + int err = nclose(); if (err) { throw GeneralException(String(_("Error during close: ")) + strerror(errno)); } +#ifndef NO_HFILE } +#endif } #if defined (_WIN32) && !defined (NO_HFILE) if (hFile) { @@ -408,7 +412,7 @@ ssize_t Handle::uwrite(const void * buf, size_t count) throw (GeneralException) itell += err; return err; } else { - itell += count = ::write(h, buf, count); + itell += count = nwrite(buf, count); return count; } } @@ -440,7 +444,7 @@ ssize_t Handle::uread(void * buf, size_t count) { itell += count = rcount; } else #endif - itell += count = ::read(h, buf, count); + itell += count = nread(buf, count); return count; } } @@ -662,3 +666,19 @@ void Handle::munmap() throw (GeneralException) { mappedarea = 0; maplength = 0; } + +ssize_t Handle::nwrite(const void * buf, size_t count) throw (GeneralException) { + return ::write(h, buf, count); +} + +ssize_t Handle::nread(void * buf, size_t count) throw (GeneralException) { + return ::read(h, buf, count); +} + +int Handle::ndup() const throw (GeneralException) { + return dup(h); +} + +int Handle::nclose() throw (GeneralException) { + return ::close(h); +} diff --git a/lib/LuaHandle.cc b/lib/LuaHandle.cc index bcade6f..a2cfe71 100644 --- a/lib/LuaHandle.cc +++ b/lib/LuaHandle.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* $Id: LuaHandle.cc,v 1.16 2005-10-13 16:00:37 pixel Exp $ */ +/* $Id: LuaHandle.cc,v 1.17 2006-01-31 17:02:39 pixel Exp $ */ #include "LuaHandle.h" @@ -635,6 +635,9 @@ void LuaHandle::pushmembers(Lua * L) { pushit(L, "read", &sLuaHandle::read); pushit(L, "write", &sLuaHandle::write); + pushit(L, "readstring", &sLuaHandle::readstring); + pushit(L, "writestring", &sLuaHandle::writestring); + pushit(L, "readU8", sLuaHandle::readU8); pushit(L, "readU16", sLuaHandle::readU16); pushit(L, "readU32", sLuaHandle::readU32); @@ -644,7 +647,6 @@ void LuaHandle::pushmembers(Lua * L) { pushit(L, "copyfrom", sLuaHandle::copyfrom); pushit(L, "copyto", sLuaHandle::copyto); - L->declarefunc("handlecopy", sLuaHandle::copyfrom); pushit(L, "isclosed", sLuaHandle::isclosed); pushit(L, "isnonblock", sLuaHandle::isnonblock); @@ -663,7 +665,10 @@ void LuaHandle::pushmembers(Lua * L) { pushit(L, "seek", sLuaHandle::seek); pushit(L, "setz", sLuaHandle::setz); - +} + +void LuaHandle::pushconstruct(Lua * L) { + L->declarefunc("handlecopy", sLuaHandle::copyfrom); L->declarefunc("exists", sLuaHandle::exists); L->push("SEEK_SET"); diff --git a/lib/Socket.cc b/lib/Socket.cc index f3e28df..5a6cede 100644 --- a/lib/Socket.cc +++ b/lib/Socket.cc @@ -1,11 +1,16 @@ +#ifdef _WIN32 +#include <winsock2.h> +#endif + #define _BSD_SOCKLEN_T_ int +#ifndef _WIN32 #include <netdb.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> -#include <errno.h> -#include <string.h> #include <strings.h> +#endif +#include <string.h> #include <errno.h> #ifdef HAVE_CONFIG_H #include "config.h" @@ -17,6 +22,19 @@ #include "Output.h" #include "gettext.h" +#ifdef _WIN32 +class dummy_win32_socket_class_t : public Base { + public: + dummy_win32_socket_class_t() throw (GeneralException) { + WSADATA wsaData; + + if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) + throw GeneralException("WSAStartup() failed."); + } +} dummy_win32_socket_class; +typedef int socklen_t; +#endif + Socket::Socket() throw (GeneralException) : Handle(socket(AF_INET, SOCK_STREAM, 0)), connected(false), listening(false), writeclosed(false), readclosed(false) { // cerr << "Socket(): connected = " << connected << "; readclosed = " << readclosed << "; writeclosed = " << writeclosed << endl; if (GetHandle() < 0) { @@ -161,3 +179,34 @@ int Socket::GetPort() { return r; } + +ssize_t Socket::nwrite(const void * buf, size_t count) throw (GeneralException) { + return ::send(GetHandle(), (const char *) buf, count, 0); +} + +ssize_t Socket::nread(void * buf, size_t count) throw (GeneralException) { + return ::recv(GetHandle(), (char *) buf, count, 0); +} + +int Socket::ndup() const throw (GeneralException) { +#ifdef _WIN32 + WSAPROTOCOL_INFO ProtocolInfo; + int r, s; + + if (r = WSADuplicateSocket(GetHandle(), GetCurrentProcessId(), &ProtocolInfo)) { + throw GeneralException("Error within WSADuplicateSocket()."); + } + + if ((s = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, &ProtocolInfo, 0, 0)) == INVALID_SOCKET) { + throw GeneralException("Error within WSASocket() while dup()ing it."); + } + + return s; +#else + return dup(GetHandle()); +#endif +} + +int Socket::nclose() throw (GeneralException) { + return closesocket(GetHandle()); +} diff --git a/lib/String.cc b/lib/String.cc index b63b216..20cade9 100644 --- a/lib/String.cc +++ b/lib/String.cc @@ -17,12 +17,13 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* $Id: String.cc,v 1.40 2005-12-01 14:30:04 pixel Exp $ */ +/* $Id: String.cc,v 1.41 2006-01-31 17:02:39 pixel Exp $ */ #include <stdio.h> #include <string.h> #include <stdarg.h> #include <ctype.h> +#include <iconv.h> #include <iostream> #ifdef HAVE_CONFIG_H #include "config.h" @@ -558,3 +559,32 @@ String String::rtrim() const { String String::trim() const { return rtrim().ltrim(); } + +String & String::iconv(const String & from, const String & to) { + iconv_t cd; + const char * inbuf; + char * outbuf; + size_t inleft, outleft; + + if ((cd = iconv_open(to.str, from.str)) == (iconv_t) (-1)) { + return *this; + } + + LOCK; + inbuf = str; + outbuf = t; + inleft = siz; + outleft = BUFSIZ; + memset(t, 0, BUFSIZ + 1); + ::iconv (cd, &inbuf, &inleft, &outbuf, &outleft); + + free(str); + + str = Base::strdup(t); + siz = ::strlen(t); + UNLOCK; + + iconv_close(cd); + + return *this; +} diff --git a/lib/Task.cc b/lib/Task.cc index afa697c..4d161ea 100644 --- a/lib/Task.cc +++ b/lib/Task.cc @@ -1,4 +1,6 @@ +#ifndef _WIN32 #include <sys/time.h> +#endif #include <iostream> #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/lib/TaskMan.cc b/lib/TaskMan.cc index 1dcf331..8b27e71 100644 --- a/lib/TaskMan.cc +++ b/lib/TaskMan.cc @@ -1,11 +1,13 @@ +#ifndef _WIN32 #include <signal.h> #include <sys/wait.h> #include <sys/poll.h> +#include <sys/time.h> +#include <unistd.h> +#endif #include <errno.h> #include <string.h> -#include <sys/time.h> #include <sys/types.h> -#include <unistd.h> #include <vector> #ifdef HAVE_CONFIG_H #include "config.h" @@ -13,8 +15,6 @@ #include "TaskMan.h" #include "gettext.h" -#define USE_POLL 1 - TaskMan::TaskList_t TaskMan::TaskList; TaskMan::TaskList_t TaskMan::Zombies; std::vector<TaskMan::w4ha_t> TaskMan::w4ha; @@ -33,6 +33,7 @@ sigset_t TaskMan::sigchildset; static int got_sigchild = 0; +#ifndef _WIN32 void taskman_sigchild(int sig) { int status; pid_t pid; @@ -51,6 +52,90 @@ void taskman_sigchild(int sig) { void taskman_sighole(int sig) { signal(sig, taskman_sighole); } +#endif + +#ifdef _WIN32 + + +#define POLLIN 1 /* Set if data to read. */ +#define POLLPRI 2 /* Set if urgent data to read. */ +#define POLLOUT 4 /* Set if writing data wouldn't block. */ +#define POLLERR 8 /* An error occured. */ +#define POLLHUP 16 /* Shutdown or close happened. */ +#define POLLNVAL 32 /* Invalid file descriptor. */ + +#define NPOLLFILE 64 /* Number of canonical fd's in one call to poll(). */ + +/* The following values are defined by XPG4. */ +#define POLLRDNORM POLLIN +#define POLLRDBAND POLLPRI +#define POLLWRNORM POLLOUT +#define POLLWRBAND POLLOUT + +struct pollfd { + int fd; + short events; + short revents; +}; + +int poll (struct pollfd *fds, unsigned int nfds, int timeout) { + fd_set read_fds, write_fds, except_fds; + struct timeval tv = { timeout / 1000, (timeout % 1000) * 1000 }; + int max_fd = 0, i, retval, changedfds; + + FD_ZERO(&read_fds); + FD_ZERO(&write_fds); + FD_ZERO(&except_fds); + + for (int i = 0; i < nfds; i++) { + if (!fds[i].fd && !fds[i].events) + continue; + + if (fds[i].fd > max_fd) + max_fd = fds[i].fd; + + if (fds[i].events & POLLIN) + FD_SET(fds[i].fd, &read_fds); + + if (fds[i].events & POLLOUT) + FD_SET(fds[i].fd, &write_fds); + + FD_SET(fds[i].fd, &except_fds); + + fds[i].revents = 0; + } + + changedfds = retval = select(max_fd + 1, &read_fds, &write_fds, &except_fds, timeout < 0 ? NULL : &tv); + + if (retval <= 0) { + // got timeout or error + return retval; + } + + for (i = 0; i < nfds; i++) { + if (FD_ISSET(fds[i].fd, &read_fds)) { + fds[i].revents |= POLLIN; + changedfds--; + } + + if (FD_ISSET(fds[i].fd, &write_fds)) { + fds[i].revents |= POLLOUT; + changedfds--; + } + + if (FD_ISSET(fds[i].fd, &except_fds)) { + fds[i].revents |= POLLERR; + changedfds--; + } + + if (changedfds <= 0) + break; + } + + return retval; +} + +#endif int TaskMan::GotChild(pid_t pid, int status) { int r = 0; @@ -72,6 +157,7 @@ void TaskMan::Init() throw (GeneralException) { throw GeneralException(_("Task Manager already initialised.")); } +#ifndef _WIN32 signal(SIGCHLD, taskman_sigchild); signal(SIGPIPE, taskman_sighole); signal(SIGHUP, taskman_sighole); @@ -79,7 +165,8 @@ void TaskMan::Init() throw (GeneralException) { sigemptyset(&sigchildset); sigaddset(&sigchildset, SIGCHLD); sigprocmask(SIG_BLOCK, &sigchildset, 0); - +#endif + inited = true; number = 0; } @@ -258,7 +345,7 @@ void TaskMan::MainLoop() throw (GeneralException) { if (t->GetState() == TASK_DONE) { TaskList.erase(p); number--; - p--; + p = TaskList.begin(); Zombies.push_back(t); } } @@ -308,21 +395,26 @@ void TaskMan::MainLoop() throw (GeneralException) { p->T->SetBurst(); no_burst = 0; p->dirthy = true; - if (!(p->flags & W4_STICKY)) { - w4ha.erase(p); - p--; - } q->fd = 0; q->events = 0; } } } + for (p = w4ha.begin(); p != w4ha.end(); p++) { + if (!p->T->IsStopped() && !p->ha->CanWatch() && !(p->flags & W4_STICKY)) { + w4ha.erase(p); + p = w4ha.begin(); + } + } } - + +#ifndef _WIN32 sigprocmask(SIG_UNBLOCK, &sigchildset, 0); +#endif r = poll(ufsd, nfds, (no_burst) && !(Zombies.size()) && !(got_sigchild) ? -1: 0); - sigprocmask(SIG_BLOCK, &sigchildset, 0); - +#ifndef _WIN32 + sigprocmask(SIG_BLOCK, &sigchildset, 0); +#endif if (r < 0) { if (errno != EINTR) { throw GeneralException(String(_("Error during poll: ")) + strerror(errno)); @@ -330,7 +422,9 @@ void TaskMan::MainLoop() throw (GeneralException) { } else if (r == 0) { // timeout. // **FIXME** +#ifndef _WIN32 #warning FIXME +#endif } else { int fd; struct pollfd * q; |