Mirror of GNU Guix
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

234 lines
5.9 KiB

  1. This patch adds bindings to Linux syscalls for which glibc has symbols.
  2. diff --git a/libguile/posix.c b/libguile/posix.c
  3. index 324f21b..ace5211 100644
  4. --- a/libguile/posix.c
  5. +++ b/libguile/posix.c
  6. @@ -2286,6 +2286,227 @@ scm_init_popen (void)
  7. }
  8. #endif
  9. +
  10. +/* Linux! */
  11. +
  12. +#include <sys/mount.h>
  13. +#include "libguile/foreign.h"
  14. +#include "libguile/bytevectors.h"
  15. +
  16. +SCM_DEFINE (scm_mount, "mount", 3, 2, 0,
  17. + (SCM source, SCM target, SCM type, SCM flags, SCM data),
  18. + "Mount file system of @var{type} specified by @var{source} "
  19. + "on @var{target}.")
  20. +#define FUNC_NAME s_scm_mount
  21. +{
  22. + int err;
  23. + char *c_source, *c_target, *c_type;
  24. + unsigned long c_flags;
  25. + void *c_data;
  26. +
  27. + c_source = scm_to_locale_string (source);
  28. + c_target = scm_to_locale_string (target);
  29. + c_type = scm_to_locale_string (type);
  30. + c_flags = SCM_UNBNDP (flags) ? 0 : scm_to_ulong (flags);
  31. + c_data = SCM_UNBNDP (data) ? NULL : scm_to_pointer (data);
  32. +
  33. + err = mount (c_source, c_target, c_type, c_flags, c_data);
  34. + if (err != 0)
  35. + err = errno;
  36. +
  37. + free (c_source);
  38. + free (c_target);
  39. + free (c_type);
  40. +
  41. + if (err != 0)
  42. + {
  43. + errno = err;
  44. + SCM_SYSERROR;
  45. + }
  46. +
  47. + return SCM_UNSPECIFIED;
  48. +}
  49. +#undef FUNC_NAME
  50. +
  51. +/* Linux's module installation syscall. See `kernel/module.c' in Linux;
  52. + the function itself is part of the GNU libc.
  53. +
  54. + Load the LEN bytes at MODULE as a kernel module, with arguments from
  55. + ARGS, a space-separated list of options. */
  56. +extern long init_module (void *module, unsigned long len, const char *args);
  57. +
  58. +SCM_DEFINE (scm_load_linux_module, "load-linux-module", 1, 1, 0,
  59. + (SCM data, SCM options),
  60. + "Load the Linux kernel module whose contents are in bytevector "
  61. + "DATA (the contents of a @code{.ko} file), with the arguments "
  62. + "from the OPTIONS string.")
  63. +#define FUNC_NAME s_scm_load_linux_module
  64. +{
  65. + long err;
  66. + void *c_data;
  67. + unsigned long c_len;
  68. + char *c_options;
  69. +
  70. + SCM_VALIDATE_BYTEVECTOR (SCM_ARG1, data);
  71. +
  72. + c_data = SCM_BYTEVECTOR_CONTENTS (data);
  73. + c_len = SCM_BYTEVECTOR_LENGTH (data);
  74. + c_options =
  75. + scm_to_locale_string (SCM_UNBNDP (options) ? scm_nullstr : options);
  76. +
  77. + err = init_module (c_data, c_len, c_options);
  78. +
  79. + free (c_options);
  80. +
  81. + if (err != 0)
  82. + {
  83. + /* XXX: `insmod' actually provides better translation of some of
  84. + the error codes. */
  85. + errno = err;
  86. + SCM_SYSERROR;
  87. + }
  88. +
  89. + return SCM_UNSPECIFIED;
  90. +}
  91. +#undef FUNC_NAME
  92. +
  93. +/* Linux network interfaces. See <linux/if.h>. */
  94. +
  95. +#include <linux/if.h>
  96. +#include <linux/sockios.h>
  97. +#include "libguile/socket.h"
  98. +
  99. +SCM_VARIABLE_INIT (flag_IFF_UP, "IFF_UP",
  100. + scm_from_int (IFF_UP));
  101. +SCM_VARIABLE_INIT (flag_IFF_BROADCAST, "IFF_BROADCAST",
  102. + scm_from_int (IFF_BROADCAST));
  103. +SCM_VARIABLE_INIT (flag_IFF_DEBUG, "IFF_DEBUG",
  104. + scm_from_int (IFF_DEBUG));
  105. +SCM_VARIABLE_INIT (flag_IFF_LOOPBACK, "IFF_LOOPBACK",
  106. + scm_from_int (IFF_LOOPBACK));
  107. +SCM_VARIABLE_INIT (flag_IFF_POINTOPOINT, "IFF_POINTOPOINT",
  108. + scm_from_int (IFF_POINTOPOINT));
  109. +SCM_VARIABLE_INIT (flag_IFF_NOTRAILERS, "IFF_NOTRAILERS",
  110. + scm_from_int (IFF_NOTRAILERS));
  111. +SCM_VARIABLE_INIT (flag_IFF_RUNNING, "IFF_RUNNING",
  112. + scm_from_int (IFF_RUNNING));
  113. +SCM_VARIABLE_INIT (flag_IFF_NOARP, "IFF_NOARP",
  114. + scm_from_int (IFF_NOARP));
  115. +SCM_VARIABLE_INIT (flag_IFF_PROMISC, "IFF_PROMISC",
  116. + scm_from_int (IFF_PROMISC));
  117. +SCM_VARIABLE_INIT (flag_IFF_ALLMULTI, "IFF_ALLMULTI",
  118. + scm_from_int (IFF_ALLMULTI));
  119. +
  120. +SCM_DEFINE (scm_set_network_interface_address, "set-network-interface-address",
  121. + 3, 0, 0,
  122. + (SCM socket, SCM name, SCM address),
  123. + "Configure network interface @var{name}.")
  124. +#define FUNC_NAME s_scm_set_network_interface_address
  125. +{
  126. + char *c_name;
  127. + struct ifreq ifr;
  128. + struct sockaddr *c_address;
  129. + size_t sa_len;
  130. + int fd, err;
  131. +
  132. + socket = SCM_COERCE_OUTPORT (socket);
  133. + SCM_VALIDATE_OPFPORT (1, socket);
  134. + fd = SCM_FPORT_FDES (socket);
  135. +
  136. + memset (&ifr, 0, sizeof ifr);
  137. + c_name = scm_to_locale_string (name);
  138. + c_address = scm_to_sockaddr (address, &sa_len);
  139. +
  140. + strncpy (ifr.ifr_name, c_name, sizeof ifr.ifr_name - 1);
  141. + memcpy (&ifr.ifr_addr, c_address, sa_len);
  142. +
  143. + err = ioctl (fd, SIOCSIFADDR, &ifr);
  144. + if (err != 0)
  145. + err = errno;
  146. +
  147. + free (c_name);
  148. + free (c_address);
  149. +
  150. + if (err != 0)
  151. + {
  152. + errno = err;
  153. + SCM_SYSERROR;
  154. + }
  155. +
  156. + return SCM_UNSPECIFIED;
  157. +}
  158. +#undef FUNC_NAME
  159. +
  160. +SCM_DEFINE (scm_set_network_interface_flags, "set-network-interface-flags",
  161. + 3, 0, 0,
  162. + (SCM socket, SCM name, SCM flags),
  163. + "Change the flags of network interface @var{name} to "
  164. + "@var{flags}.")
  165. +#define FUNC_NAME s_scm_set_network_interface_flags
  166. +{
  167. + struct ifreq ifr;
  168. + char *c_name;
  169. + int fd, err;
  170. +
  171. + socket = SCM_COERCE_OUTPORT (socket);
  172. + SCM_VALIDATE_OPFPORT (1, socket);
  173. + fd = SCM_FPORT_FDES (socket);
  174. +
  175. + memset (&ifr, 0, sizeof ifr);
  176. + c_name = scm_to_locale_string (name);
  177. + strncpy (ifr.ifr_name, c_name, sizeof ifr.ifr_name - 1);
  178. + ifr.ifr_flags = scm_to_short (flags);
  179. +
  180. + err = ioctl (fd, SIOCSIFFLAGS, &ifr);
  181. + if (err != 0)
  182. + err = errno;
  183. +
  184. + free (c_name);
  185. +
  186. + if (err != 0)
  187. + {
  188. + errno = err;
  189. + SCM_SYSERROR;
  190. + }
  191. +
  192. + return SCM_UNSPECIFIED;
  193. +}
  194. +#undef FUNC_NAME
  195. +
  196. +SCM_DEFINE (scm_network_interface_flags, "network-interface-flags",
  197. + 2, 0, 0,
  198. + (SCM socket, SCM name),
  199. + "Return the flags of network interface @var{name}.")
  200. +#define FUNC_NAME s_scm_network_interface_flags
  201. +{
  202. + struct ifreq ifr;
  203. + char *c_name;
  204. + int fd, err;
  205. +
  206. + socket = SCM_COERCE_OUTPORT (socket);
  207. + SCM_VALIDATE_OPFPORT (1, socket);
  208. + fd = SCM_FPORT_FDES (socket);
  209. +
  210. + memset (&ifr, 0, sizeof ifr);
  211. + c_name = scm_to_locale_string (name);
  212. + strncpy (ifr.ifr_name, c_name, sizeof ifr.ifr_name - 1);
  213. +
  214. + err = ioctl (fd, SIOCGIFFLAGS, &ifr);
  215. + if (err != 0)
  216. + err = errno;
  217. +
  218. + free (c_name);
  219. +
  220. + if (err != 0)
  221. + {
  222. + errno = err;
  223. + SCM_SYSERROR;
  224. + }
  225. +
  226. + return scm_from_short (ifr.ifr_flags);
  227. +}
  228. +#undef FUNC_NAME
  229. +
  230. void
  231. scm_init_posix ()
  232. {