summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Modules/config.c.in5
-rw-r--r--Modules/cstubs12
-rw-r--r--Modules/socketmodule.c64
3 files changed, 63 insertions, 18 deletions
diff --git a/Modules/config.c.in b/Modules/config.c.in
index 4103075..ef1cb58 100644
--- a/Modules/config.c.in
+++ b/Modules/config.c.in
@@ -27,12 +27,13 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
/* These modules are normally always included, but *may* be taken out */
#define USE_GRP 1 /* Use together with pwd */
#define USE_MARSHAL 1 /* This is linked anyway */
+#define USE_MATH 1
#define USE_PWD 1 /* Use together with grp */
#define USE_POSIX 1
#define USE_SELECT 1
#define USE_SOCKET 1
+#define USE_STRUCT 1
#define USE_TIME 1
-#define USE_MATH 1
#include "PROTO.h"
#include "mymalloc.h"
@@ -318,7 +319,7 @@ struct {
{"stdwin", initstdwin},
#endif
-#ifdef USE_STRUCT
+#ifdef USE_STROP
{"strop", initstrop},
#endif
diff --git a/Modules/cstubs b/Modules/cstubs
index 76feb6a..6ff8f54 100644
--- a/Modules/cstubs
+++ b/Modules/cstubs
@@ -801,6 +801,18 @@ gl_unpackrect(self, args)
return unpacked;
}
+% gversion
+static object *
+gl_gversion(self, args)
+ object *self;
+ object *args;
+{
+ char buf[20];
+ gversion(buf);
+ return newstringobject(buf);
+}
+
+
/* End of manually written stubs */
%%
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
index ab8c6b5..b1ab96d 100644
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -384,8 +384,10 @@ sock_allowbroadcast(s, args)
}
-/* s.setsockopt() method */
-/* XXX this works for integer flags only */
+/* s.setsockopt() method.
+ With an integer third argument, sets an integer option.
+ With a string third argument, sets an option from a buffer;
+ use optional built-in module 'struct' to encode the string. */
static object *
sock_setsockopt(s, args)
@@ -394,12 +396,21 @@ sock_setsockopt(s, args)
{
int level;
int optname;
- int flag;
int res;
+ char *buf;
+ int buflen;
+ int flag;
- if (!getargs(args, "(iii)", &level, &optname, &flag))
- return NULL;
- res = setsockopt(s->sock_fd, level, optname, &flag, sizeof flag);
+ if (getargs(args, "(iii)", &level, &optname, &flag)) {
+ buf = (char *) &flag;
+ buflen = sizeof flag;
+ }
+ else {
+ err_clear();
+ if (!getargs(args, "(iis#)", &level, &optname, &buf, &buflen))
+ return NULL;
+ }
+ res = setsockopt(s->sock_fd, level, optname, buf, buflen);
if (res < 0)
return socket_error();
INCREF(None);
@@ -407,8 +418,10 @@ sock_setsockopt(s, args)
}
-/* s.getsockopt() method */
-/* XXX this works for integer flags only */
+/* s.getsockopt() method.
+ With two arguments, retrieves an integer option.
+ With a third integer argument, retrieves a string buffer of that size;
+ use optional built-in module 'struct' to decode the string. */
static object *
sock_getsockopt(s, args)
@@ -417,18 +430,37 @@ sock_getsockopt(s, args)
{
int level;
int optname;
- int flag;
- int flagsize;
int res;
+ object *buf;
+ int buflen;
+ int flag;
- if (!getargs(args, "(ii)", &level, &optname))
+ if (getargs(args, "(ii)", &level, &optname)) {
+ int flag = 0;
+ int flagsize = sizeof flag;
+ res = getsockopt(s->sock_fd, level, optname, &flag, &flagsize);
+ if (res < 0)
+ return socket_error();
+ return newintobject(flag);
+ }
+ err_clear();
+ if (!getargs(args, "(iii)", &level, &optname, &buflen))
return NULL;
- flagsize = sizeof flag;
- flag = 0;
- res = getsockopt(s->sock_fd, level, optname, &flag, &flagsize);
- if (res < 0)
+ if (buflen <= 0 || buflen > 1024) {
+ err_setstr(SocketError, "getsockopt buflen out of range");
+ return NULL;
+ }
+ buf = newsizedstringobject((char *)NULL, buflen);
+ if (buf == NULL)
+ return NULL;
+ res = getsockopt(s->sock_fd, level, optname, getstringvalue(buf),
+ &buflen);
+ if (res < 0) {
+ DECREF(buf);
return socket_error();
- return newintobject(flag);
+ }
+ resizestring(&buf, buflen);
+ return buf;
}