+/* Datagram sockets */
+
+/* GSocket_SetNonOriented:
+ * Sets up this socket as a non-connection oriented (datagram) socket.
+ * Before using this function, the local address must have been set
+ * with GSocket_SetLocal(), or the call will fail. Returns GSOCK_NOERROR
+ * on success, or one of the following otherwise.
+ *
+ * Error codes:
+ * GSOCK_INVSOCK - the socket is in use.
+ * GSOCK_INVADDR - the local address has not been set.
+ * GSOCK_IOERR - low-level error.
+ */
+GSocketError GSocket_SetNonOriented(GSocket *sck)
+{
+ u_long arg = 1;
+
+ assert(sck != NULL);
+
+ if (sck->m_fd != INVALID_SOCKET)
+ {
+ sck->m_error = GSOCK_INVSOCK;
+ return GSOCK_INVSOCK;
+ }
+
+ if (!sck->m_local)
+ {
+ sck->m_error = GSOCK_INVADDR;
+ return GSOCK_INVADDR;
+ }
+
+ /* Initialize all fields */
+ sck->m_stream = FALSE;
+ sck->m_server = FALSE;
+ sck->m_oriented = FALSE;
+
+ /* Create the socket */
+ sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_DGRAM, 0);
+
+ if (sck->m_fd == INVALID_SOCKET)
+ {
+ sck->m_error = GSOCK_IOERR;
+ return GSOCK_IOERR;
+ }
+
+ ioctlsocket(sck->m_fd, FIONBIO, (u_long FAR *) &arg);
+ _GSocket_Enable_Events(sck);
+
+ /* Bind to the local address,
+ * and retrieve the actual address bound.
+ */
+ if ((bind(sck->m_fd, sck->m_local->m_addr, sck->m_local->m_len) != 0) ||
+ (getsockname(sck->m_fd,
+ sck->m_local->m_addr,
+ (SOCKLEN_T *)&sck->m_local->m_len) != 0))
+ {
+ closesocket(sck->m_fd);
+ sck->m_fd = INVALID_SOCKET;
+ sck->m_error = GSOCK_IOERR;
+ return GSOCK_IOERR;
+ }
+
+ return GSOCK_NOERROR;
+}
+
+