static void term_sockdev ( void* arg ) { UNREFERENCED( arg ); if (!init_done) init_sockdev(); SIGNAL_SOCKDEV_THREAD(); join_thread ( sysblk.socktid, NULL ); detach_thread ( sysblk.socktid ); }
/*-------------------------------------------------------------------*/ int unbind_device_ex (DEVBLK* dev, int forced) { bind_struct* bs; logdebug("unbind_device(%4.4X)\n", dev->devnum); /* Error if device not bound */ if (!(bs = dev->bs)) { logmsg (_("HHCSD005E Device %4.4X not bound to any socket\n"), dev->devnum); return 0; /* (failure) */ } /* Is anyone still connected? */ if (dev->fd != -1) { /* Yes. Should we forcibly disconnect them? */ if (forced) { /* Yes. Then do so... */ close_socket( dev->fd ); dev->fd = -1; logmsg (_("HHCSD025I Client %s (%s) disconnected from device %4.4X (%s)\n"), dev->bs->clientip, dev->bs->clientname, dev->devnum, dev->bs->spec); } else { /* No. Then fail the request. */ logmsg (_("HHCSD006E Client %s (%s) still connected to device %4.4X (%s)\n"), dev->bs->clientip, dev->bs->clientname, dev->devnum, dev->bs->spec); return 0; /* (failure) */ } } /* Remove the entry from our list */ obtain_lock( &bind_lock ); RemoveListEntry( &bs->bind_link ); SIGNAL_SOCKDEV_THREAD(); release_lock( &bind_lock ); logmsg (_("HHCSD007I Device %4.4X unbound from socket %s\n"), dev->devnum, bs->spec); if (bs->sd != -1) close_socket (bs->sd); /* Unchain device and bind_struct from each another */ dev->bs = NULL; bs->dev = NULL; /* Discard the entry */ if ( bs->clientname ) free( bs->clientname ); if ( bs->clientip ) free( bs->clientip ); bs->clientname = NULL; bs->clientip = NULL; free ( bs->spec ); free ( bs ); return 1; /* (success) */ }
/*-------------------------------------------------------------------*/ int unbind_device_ex (DEVBLK* dev, int forced) { bind_struct* bs; logdebug("unbind_device(%4.4X)\n", dev->devnum); /* Error if device not bound */ if (!(bs = dev->bs)) { WRMSG (HHC01043, "E", SSID_TO_LCSS(dev->ssid), dev->devnum); return 0; /* (failure) */ } /* Is anyone still connected? */ if (dev->fd != -1) { /* Yes. Should we forcibly disconnect them? */ if (forced) { /* Yes. Then do so... */ close_socket( dev->fd ); dev->fd = -1; WRMSG (HHC01044, "I", SSID_TO_LCSS(dev->ssid), dev->devnum, dev->bs->clientip, dev->bs->clientname, dev->bs->spec); } else { /* No. Then fail the request. */ WRMSG (HHC01045, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, dev->bs->clientip, dev->bs->clientname, dev->bs->spec); return 0; /* (failure) */ } } /* Remove the entry from our list */ obtain_lock( &bind_lock ); RemoveListEntry( &bs->bind_link ); SIGNAL_SOCKDEV_THREAD(); release_lock( &bind_lock ); WRMSG (HHC01046, "I",SSID_TO_LCSS(dev->ssid), dev->devnum, bs->spec); if (bs->sd != -1) close_socket (bs->sd); /* Unchain device and bind_struct from each another */ dev->bs = NULL; bs->dev = NULL; /* Discard the entry */ if ( bs->clientname ) free( bs->clientname ); if ( bs->clientip ) free( bs->clientip ); bs->clientname = NULL; bs->clientip = NULL; free ( bs->spec ); free ( bs ); return 1; /* (success) */ }
/*-------------------------------------------------------------------*/ int bind_device_ex (DEVBLK* dev, char* spec, ONCONNECT fn, void* arg ) { bind_struct* bs; int was_list_empty; if (!init_done) init_sockdev(); if (sysblk.shutdown) return 0; logdebug("bind_device (%4.4X, %s)\n", dev->devnum, spec); /* Error if device already bound */ if (dev->bs) { logmsg (_("HHCSD001E Device %4.4X already bound to socket %s\n"), dev->devnum, dev->bs->spec); return 0; /* (failure) */ } /* Create a new bind_struct entry */ bs = malloc(sizeof(bind_struct)); if (!bs) { logmsg (_("HHCSD002E bind_device malloc() failed for device %4.4X\n"), dev->devnum); return 0; /* (failure) */ } memset(bs,0,sizeof(bind_struct)); bs->fn = fn; bs->arg = arg; if (!(bs->spec = strdup(spec))) { logmsg (_("HHCSD003E bind_device strdup() failed for device %4.4X\n"), dev->devnum); free (bs); return 0; /* (failure) */ } /* Create a listening socket */ if (bs->spec[0] == '/') bs->sd = unix_socket (bs->spec); else bs->sd = inet_socket (bs->spec); if (bs->sd == -1) { /* (error message already issued) */ free( bs->spec ); free( bs ); return 0; /* (failure) */ } /* Chain device and bind_struct to each other */ dev->bs = bs; bs->dev = dev; /* Add the new entry to our list of bound devices and create the socket thread that will listen for connections (if it doesn't already exist) */ obtain_lock( &bind_lock ); was_list_empty = IsListEmpty( &bind_head ); InsertListTail( &bind_head, &bs->bind_link ); if ( was_list_empty ) { if ( create_thread( &sysblk.socktid, JOINABLE, socket_thread, NULL, "socket_thread" ) ) { logmsg( _( "HHCSD023E Cannot create socketdevice thread: errno=%d: %s\n" ), errno, strerror( errno ) ); RemoveListEntry( &bs->bind_link ); close_socket(bs->sd); free( bs->spec ); free( bs ); release_lock( &bind_lock ); return 0; /* (failure) */ } } SIGNAL_SOCKDEV_THREAD(); release_lock( &bind_lock ); logmsg (_("HHCSD004I Device %4.4X bound to socket %s\n"), dev->devnum, dev->bs->spec); return 1; /* (success) */ }
/*-------------------------------------------------------------------*/ int bind_device_ex (DEVBLK* dev, char* spec, ONCONNECT fn, void* arg ) { bind_struct* bs; int was_list_empty; int rc; if (!init_done) init_sockdev(); if (sysblk.shutdown) return 0; logdebug("bind_device (%4.4X, %s)\n", dev->devnum, spec); /* Error if device already bound */ if (dev->bs) { WRMSG (HHC01041, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, dev->bs->spec); return 0; /* (failure) */ } /* Create a new bind_struct entry */ bs = malloc(sizeof(bind_struct)); if (!bs) { char buf[40]; MSGBUF( buf, "malloc(%d)", (int)sizeof(bind_struct)); WRMSG (HHC01000, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, buf, strerror(errno)); return 0; /* (failure) */ } memset(bs, 0, sizeof(bind_struct)); bs->fn = fn; bs->arg = arg; if (!(bs->spec = strdup(spec))) { WRMSG (HHC01000, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, "strdup()", strerror(errno) ); free (bs); return 0; /* (failure) */ } /* Create a listening socket */ if (bs->spec[0] == '/') bs->sd = unix_socket (bs->spec); else bs->sd = inet_socket (bs->spec); if (bs->sd == -1) { /* (error message already issued) */ free( bs->spec ); free( bs ); return 0; /* (failure) */ } /* Chain device and bind_struct to each other */ dev->bs = bs; bs->dev = dev; /* Add the new entry to our list of bound devices and create the socket thread that will listen for connections (if it doesn't already exist) */ obtain_lock( &bind_lock ); was_list_empty = IsListEmpty( &bind_head ); InsertListTail( &bind_head, &bs->bind_link ); if ( was_list_empty ) { rc = create_thread( &sysblk.socktid, JOINABLE, socket_thread, NULL, "socket_thread" ); if (rc) { WRMSG(HHC00102, "E", strerror( rc ) ); RemoveListEntry( &bs->bind_link ); close_socket(bs->sd); free( bs->spec ); free( bs ); release_lock( &bind_lock ); return 0; /* (failure) */ } } SIGNAL_SOCKDEV_THREAD(); release_lock( &bind_lock ); WRMSG (HHC01042, "I", SSID_TO_LCSS(dev->ssid), dev->devnum, dev->bs->spec); return 1; /* (success) */ }