@@ -3338,26 +3338,32 @@ sock_setsockopt(PyObject *self, PyObject *args)
33383338 Py_buffer optval ;
33393339 int flag ;
33403340 unsigned int optlen ;
3341- PyObject * none ;
3341+ PyObject * type ;
3342+
3343+ if (!PyArg_ParseTuple (args , "iiO|I:setsockopt" ,
3344+ & level , & optname , & type , & optlen )) {
3345+ return NULL ;
3346+ }
33423347
33433348#ifdef AF_VSOCK
33443349 if (s -> sock_family == AF_VSOCK ) {
33453350 uint64_t vflag ; // Must be set width of 64 bits
33463351 /* setsockopt(level, opt, flag) */
3347- if (PyArg_ParseTuple (args , "iiK:setsockopt" ,
3348- & level , & optname , & vflag )) {
3349- // level should always be set to AF_VSOCK
3350- res = setsockopt (get_sock_fd (s ), level , optname ,
3351- (void * )& vflag , sizeof vflag );
3352- goto done ;
3352+ if (!PyArg_Parse (type , "K" , & vflag )) {
3353+ return NULL ;
33533354 }
3354- return NULL ;
3355+ // level should always be set to AF_VSOCK
3356+ res = setsockopt (get_sock_fd (s ), level , optname ,
3357+ (void * )& vflag , sizeof vflag );
3358+ goto done ;
33553359 }
33563360#endif
33573361
33583362 /* setsockopt(level, opt, flag) */
3359- if (PyArg_ParseTuple (args , "iii:setsockopt" ,
3360- & level , & optname , & flag )) {
3363+ if (PyIndex_Check (type )) {
3364+ if (!PyArg_Parse (type , "i" , & flag )) {
3365+ return NULL ;
3366+ }
33613367#ifdef MS_WINDOWS
33623368 if (optname == SIO_TCP_SET_ACK_FREQUENCY ) {
33633369 DWORD dummy ;
@@ -3373,43 +3379,40 @@ sock_setsockopt(PyObject *self, PyObject *args)
33733379 (char * )& flag , sizeof flag );
33743380 goto done ;
33753381 }
3376- if (!PyErr_ExceptionMatches (PyExc_TypeError )) {
3377- return NULL ;
3378- }
33793382
3380- PyErr_Clear ();
33813383 /* setsockopt(level, opt, None, flag) */
3382- if (PyArg_ParseTuple (args , "iiO!I:setsockopt" ,
3383- & level , & optname , Py_TYPE (Py_None ), & none , & optlen )) {
3384+ if (type == Py_None ) {
33843385 assert (sizeof (socklen_t ) >= sizeof (unsigned int ));
33853386 res = setsockopt (get_sock_fd (s ), level , optname ,
33863387 NULL , (socklen_t )optlen );
33873388 goto done ;
33883389 }
3389- if (!PyErr_ExceptionMatches (PyExc_TypeError )) {
3390- return NULL ;
3391- }
33923390
3393- PyErr_Clear ();
33943391 /* setsockopt(level, opt, buffer) */
3395- if (! PyArg_ParseTuple ( args , "iiy*:setsockopt" ,
3396- & level , & optname , & optval ))
3397- return NULL ;
3398-
3392+ if (PyObject_CheckBuffer ( type )) {
3393+ if (! PyArg_Parse ( type , "y*" , & optval )) {
3394+ return NULL ;
3395+ }
33993396#ifdef MS_WINDOWS
3400- if (optval .len > INT_MAX ) {
3401- PyBuffer_Release (& optval );
3402- PyErr_Format (PyExc_OverflowError ,
3403- "socket option is larger than %i bytes" ,
3404- INT_MAX );
3405- return NULL ;
3406- }
3407- res = setsockopt (get_sock_fd (s ), level , optname ,
3408- optval .buf , (int )optval .len );
3397+ if (optval .len > INT_MAX ) {
3398+ PyBuffer_Release (& optval );
3399+ PyErr_Format (PyExc_OverflowError ,
3400+ "socket option is larger than %i bytes" ,
3401+ INT_MAX );
3402+ return NULL ;
3403+ }
3404+ res = setsockopt (get_sock_fd (s ), level , optname ,
3405+ optval .buf , (int )optval .len );
34093406#else
3410- res = setsockopt (get_sock_fd (s ), level , optname , optval .buf , optval .len );
3407+ res = setsockopt (get_sock_fd (s ), level , optname , optval .buf , optval .len );
34113408#endif
3412- PyBuffer_Release (& optval );
3409+ PyBuffer_Release (& optval );
3410+ goto done ;
3411+ }
3412+
3413+ PyErr_Format (PyExc_TypeError ,
3414+ "socket option should be integer, bytes-like object or None" );
3415+ return NULL ;
34133416
34143417done :
34153418 if (res < 0 ) {
0 commit comments