+
+/**
+ * g_socket_get_option:
+ * @socket: a #GSocket
+ * @level: the "API level" of the option (eg, `SOL_SOCKET`)
+ * @optname: the "name" of the option (eg, `SO_BROADCAST`)
+ * @value: (out): return location for the option value
+ * @error: #GError for error reporting, or %NULL to ignore.
+ *
+ * Gets the value of an integer-valued option on @socket, as with
+ * getsockopt(). (If you need to fetch a non-integer-valued option,
+ * you will need to call getsockopt() directly.)
+ *
+ * The [<gio/gnetworking.h>][gio-gnetworking.h]
+ * header pulls in system headers that will define most of the
+ * standard/portable socket options. For unusual socket protocols or
+ * platform-dependent options, you may need to include additional
+ * headers.
+ *
+ * Note that even for socket options that are a single byte in size,
+ * @value is still a pointer to a #gint variable, not a #guchar;
+ * g_socket_get_option() will handle the conversion internally.
+ *
+ * Returns: success or failure. On failure, @error will be set, and
+ * the system error value (`errno` or WSAGetLastError()) will still
+ * be set to the result of the getsockopt() call.
+ *
+ * Since: 2.36
+ */
+gboolean
+g_socket_get_option (GSocket *socket,
+ gint level,
+ gint optname,
+ gint *value,
+ GError **error)
+{
+ guint size;
+
+ g_return_val_if_fail (G_IS_SOCKET (socket), FALSE);
+
+ *value = 0;
+ size = sizeof (gint);
+ if (getsockopt (socket->priv->fd, level, optname, value, &size) != 0)
+ {
+ int errsv = get_socket_errno ();
+
+ g_set_error_literal (error,
+ G_IO_ERROR,
+ socket_io_error_from_errno (errsv),
+ socket_strerror (errsv));
+#ifndef G_OS_WIN32
+ /* Reset errno in case the caller wants to look at it */
+ errno = errsv;
+#endif
+ return FALSE;
+ }
+
+#if G_BYTE_ORDER == G_BIG_ENDIAN
+ /* If the returned value is smaller than an int then we need to
+ * slide it over into the low-order bytes of *value.
+ */
+ if (size != sizeof (gint))
+ *value = *value >> (8 * (sizeof (gint) - size));
+#endif
+
+ return TRUE;
+}
+
+/**
+ * g_socket_set_option:
+ * @socket: a #GSocket
+ * @level: the "API level" of the option (eg, `SOL_SOCKET`)
+ * @optname: the "name" of the option (eg, `SO_BROADCAST`)
+ * @value: the value to set the option to
+ * @error: #GError for error reporting, or %NULL to ignore.
+ *
+ * Sets the value of an integer-valued option on @socket, as with
+ * setsockopt(). (If you need to set a non-integer-valued option,
+ * you will need to call setsockopt() directly.)
+ *
+ * The [<gio/gnetworking.h>][gio-gnetworking.h]
+ * header pulls in system headers that will define most of the
+ * standard/portable socket options. For unusual socket protocols or
+ * platform-dependent options, you may need to include additional
+ * headers.
+ *
+ * Returns: success or failure. On failure, @error will be set, and
+ * the system error value (`errno` or WSAGetLastError()) will still
+ * be set to the result of the setsockopt() call.
+ *
+ * Since: 2.36
+ */
+gboolean
+g_socket_set_option (GSocket *socket,
+ gint level,
+ gint optname,
+ gint value,
+ GError **error)
+{
+ gint errsv;
+
+ g_return_val_if_fail (G_IS_SOCKET (socket), FALSE);
+
+ if (setsockopt (socket->priv->fd, level, optname, &value, sizeof (gint)) == 0)
+ return TRUE;
+
+#if !defined (__linux__) && !defined (G_OS_WIN32)
+ /* Linux and Windows let you set a single-byte value from an int,
+ * but most other platforms don't.
+ */
+ if (errno == EINVAL && value >= SCHAR_MIN && value <= CHAR_MAX)
+ {
+#if G_BYTE_ORDER == G_BIG_ENDIAN
+ value = value << (8 * (sizeof (gint) - 1));
+#endif
+ if (setsockopt (socket->priv->fd, level, optname, &value, 1) == 0)
+ return TRUE;
+ }
+#endif
+
+ errsv = get_socket_errno ();
+
+ g_set_error_literal (error,
+ G_IO_ERROR,
+ socket_io_error_from_errno (errsv),
+ socket_strerror (errsv));
+#ifndef G_OS_WIN32
+ errno = errsv;
+#endif
+ return FALSE;
+}
+