summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/BLua.cc38
-rw-r--r--lib/CopyJob.cc14
-rw-r--r--lib/Handle.cc36
-rw-r--r--lib/LuaHandle.cc11
-rw-r--r--lib/Socket.cc53
-rw-r--r--lib/String.cc32
-rw-r--r--lib/Task.cc2
-rw-r--r--lib/TaskMan.cc120
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;