El problema se resolvió actualizando la biblioteca C.
Me gustaría usar el syscall getrandom ( http://man7.org/linux/man-pages/man2/getrandom.2.html )
gcc-5 -std=c11 prueba.c
#include <sys/types.h> #include <sys/stat.h> #include <sys/fcntl.h> #include <errno.h> #include <string.h> #include <signal.h> #include <linux/random.h> #include <sys/syscall.h> int main(void) { void *buf = NULL; size_t l = 5; unsigned int o = 1; int r = syscall(SYS_getrandom, buf, l, o); return 0; }
o
int main(void) { void *buf = NULL; size_t l = 5; unsigned int o = 1; int r = getrandom(buf, l, o); return 0; }
De todos modos, cuando intento compilarlo con gcc-5:
test.c: In function 'main': test.c:14:17: warning: implicit declaration of function 'getrandom' [-Wimplicit-function-declaration] int r = getrandom(buf, l, o); ^ /tmp/ccqFdJAJ.o: In function `main': test.c:(.text+0x36): undefined reference to `getrandom' collect2: error: ld returned 1 exit status
Estoy usando Ubuntu 14.04, ¿qué puedo hacer para usar getrandom? Como es un syscall "nuevo", ¿cómo puedo usarlo?
editar:
uname -r -> 4.0.3-040003-generic #201505131441 SMP Wed May 13 13:43:16 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
cuando reemplazo r por int r = syscall(SYS_getrandom, buf, l, o);
o r = getrandom(buf, l, o) es lo mismo..
Entonces, parece que getrandom
no es una función, solo una llamada al sistema.
Por lo tanto, esto es necesario:
/* Note that this define is required for syscalls to work. */ #define _GNU_SOURCE #include <unistd.h> #include <sys/syscall.h> #include <linux/random.h> int main(int arg, char *argv[]) { void *buf = NULL; size_t l = 5; unsigned int o = 1; int r = syscall(SYS_getrandom, buf, l, o); return 0; }
getrandom
y getentropy
se agregaron a glibc en la versión 2.25 . A partir de julio de 2017, la mayoría de las distribuciones de Linux aún no se han actualizado a esta versión (por ejemplo, la versión más reciente de Debian, que acaba de salir, tiene la 2.24), pero lo harán pronto.
A continuación se explica cómo utilizar los envoltorios glibc, si están disponibles, y recurrir a la llamada del sistema sin formato si no es así:
#define _GNU_SOURCE 1 #include <sys/types.h> #include <unistd.h> #if defined __GLIBC__ && defined __linux__ # if __GLIBC__ > 2 || __GLIBC_MINOR__ > 24 # include <sys/random.h> int my_getentropy(void *buf, size_t buflen) { return getentropy(buf, buflen); } # else /* older glibc */ # include <sys/syscall.h> # include <errno.h> int my_getentropy(void *buf, size_t buflen) { if (buflen > 256) { errno = EIO; return -1; } return syscall(SYS_getrandom, buf, buflen, 0); } # endif #else /* not linux or not glibc */ #error "Need implementation for whatever operating system this is" #endif
(Como se señaló en otras respuestas, también es necesario asegurarse de tener el kernel 3.17 o más reciente. Ambas versiones anteriores de my_getentropy
fallarán y establecerán errno
en ENOSYS
si se ejecutan en un kernel anterior).
La getrandom()
se introdujo en el kernel de Linux 3.17. Ubuntu 14.04 se envía con el kernel 3.13, por lo que debe actualizar a un kernel más reciente para obtener la llamada al sistema.
Para obtener paquetes .deb del kernel de Linux para Ubuntu, eche un vistazo a kernel.ubuntu.com . Este problema también se discutió en askubuntu.com .