// macros for sockopts #define GETSOCKOPT() \ vlen = (socklen_t)sizeof(val);\ if (getsockopt (s->fd, level, opt, &val, &vlen) < 0)\ SOCKET_ERROR ("socket-getsockopt") #define SETSOCKOPT() \ vlen = (socklen_t)sizeof(val);\ if (setsockopt (s->fd, level, opt, &val, vlen) < 0)\ SOCKET_ERROR ("socket-setsockopt");\ return scheme_void #define GETSOCKOPT_bool() \ {\ int val;\ GETSOCKOPT();\ return BOOLEAN (val);\ } #define SETSOCKOPT_bool() \ {\ int val;\ EXPECT_BOOLEAN ("socket-setsockopt", 3);\ val = BOOLEAN_VAL (argv[3]);\ SETSOCKOPT();\ } #define GETSOCKOPT_int() \ {\ int val;\ GETSOCKOPT();\ return FIXNUM( val );\ } #define SETSOCKOPT_int() \ {\ int val;\ EXPECT_FIXNUM ("socket-setsockopt", 3);\ val = FIXNUM_VAL (argv[3]);\ SETSOCKOPT();\ } #define GETSOCKOPT_timeval() \ {\ struct timeval val;\ GETSOCKOPT();\ return FLONUM (val.tv_sec + val.tv_usec * 1e6);\ } #define SETSOCKOPT_timeval() \ {\ double sval;\ struct timeval val;\ EXPECT_FLONUM ("socket-setsockopt", 3);\ sval = FLONUM_VAL( argv[3] );\ val.tv_sec = (int)sval;\ val.tv_usec = (int)((sval - val.tv_sec) * 1e6);\ SETSOCKOPT();\ } #define GETSOCKOPT_bytes(_len) \ {\ char val[_len];\ GETSOCKOPT();\ return BYTES_SIZE (val, _len);\ } #define SETSOCKOPT_bytes(_len) \ {\ char val[_len];\ EXPECT_BYTES( "socket-setsockopt", 3 );\ if (__CHECKT (BYTES_LEN (argv[3]) < sizeof(val))) \ ERROR( "socket-setsockopt: bad value length" );\ memcpy (val, BYTES_VAL( argv[3] ), sizeof(val));\ SETSOCKOPT();\ } #define GETSOCKOPT_in_addr() \ {\ struct in_addr val;\ GETSOCKOPT();\ return inet_ntop_bytes (AF_INET, &val);\ } #define SETSOCKOPT_in_addr() \ {\ struct in_addr val;\ EXPECT_BYTES ("socket-setsockopt", 3);\ if (__CHECKT (!(inet_pton (AF_INET, BYTES_VAL (argv[3]), &val) > 0))) { \ ERROR ("socket-setsockopt: bad address");\ }\ SETSOCKOPT();\ } #define GETSOCKOPT_in6_addr() \ {\ struct in6_addr val;\ GETSOCKOPT();\ return inet_ntop_bytes( AF_INET6, &val );\ } #define SETSOCKOPT_in6_addr() \ {\ struct in6_addr val;\ EXPECT_BYTES ("socket-setsockopt", 3);\ if (__CHECKT (!(inet_pton (AF_INET6, BYTES_VAL (argv[3]), &val) > 0))) { \ ERROR ("socket-setsockopt: bad address");\ }\ SETSOCKOPT();\ } #define SETSOCKOPT_ip_mreq() \ {\ struct ip_mreq val;\ EXPECT_PAIR ("socket-setsockopt", 3);\ if (BYTESP (CAR (argv[3]))) {\ if (__CHECKT (!(inet_pton (AF_INET, BYTES_VAL (CAR (argv[3])), \ &val.imr_multiaddr ) > 0))) { \ ERROR ("socket-setsockopt: bad address");\ }\ } else scheme_arg_mismatch ("socket-setsockopt", \ "ip_mreq: (bytes) or (bytes . bytes)",\ argv[3]);\ if (NULLP (CDR (argv[3]))) {\ val.imr_interface.s_addr = htonl (INADDR_ANY);\ } else if (BYTESP (CDR( argv[3]))) {\ if (__CHECKT (!(inet_pton (AF_INET, BYTES_VAL (CDR (argv[3])), \ &val.imr_interface) > 0))) { \ ERROR ("socket-setsockopt: bad address");\ }\ } else scheme_arg_mismatch ("socket-setsockopt", \ "ip_mreq: (bytes) or (bytes . bytes)",\ argv[3]);\ SETSOCKOPT();\ } #define SETSOCKOPT_ipv6_mreq() \ {\ struct ipv6_mreq val;\ EXPECT_PAIR ("socket-setsockopt", 3);\ if (BYTESP (CAR (argv[3]))) {\ if (__CHECKT (!(inet_pton (AF_INET6, BYTES_VAL (CAR (argv[3])), \ &val.ipv6mr_multiaddr) > 0))) { \ ERROR ("socket-setsockopt: bad address");\ }\ } else scheme_arg_mismatch ("socket-setsockopt", \ "ipv6_mreq: (bytes) or (bytes . int)", \ argv[3]); \ if (NULLP (CDR (argv[3]))) {\ val.ipv6mr_interface = 0;\ } else if (FIXNUMP (CDR (argv[3]))) {\ val.ipv6mr_interface = FIXNUM_VAL (CDR( argv[3]));\ } else scheme_arg_mismatch ("socket-setsockopt", \ "ipv6_mreq: (bytes) or (bytes . int)", \ argv[3]); \ SETSOCKOPT();\ }