2015-06-12 7 views
6

समस्या सी पुस्तकालय को अपग्रेड करके हल किया गया था।सी में getrandom syscall नहीं मिला


मैं (http://man7.org/linux/man-pages/man2/getrandom.2.html)

जीसीसी -5 -std = C11 test.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; 
} 

या

int main(void) 
    { 
      void *buf = NULL; 
      size_t l = 5; 
      unsigned int o = 1; 
      int r = getrandom(buf, l, o); 
      return 0; 
    } 

वैसे भी जब syscall getrandom उपयोग करना चाहते हैं मैं इसे जीसीसी -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 

मैं उबंटू 14.04 का उपयोग कर रहा हूं, मैं गेट्रैंडम का उपयोग करने के लिए क्या कर सकता हूं? चूंकि यह एक "नया" syscall है, मैं इसका उपयोग कैसे कर सकता हूं?

संपादित करें:

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 

जब मैं द्वारा आर की जगह int r = syscall(SYS_getrandom, buf, l, o); या आर = getrandom (buf, एल, ओ) यह एक ही है ..

+1

अपने संपादन का जिक्र करते हुए: इसका उपयोग करते समय प्रोटोटाइप को 'syscall()' में जोड़ें! यह ' '' SYS_getrandom' में भी उपलब्ध होना चाहिए। – alk

+0

आप [यादृच्छिक (4)] (http://man7.org/linux/man-pages/man4/random.4.html) का उपयोग क्यों नहीं करते हैं, यानी '/ dev/random' से कुछ बाइट्स पढ़ते हैं? –

+0

नहीं, लेकिन आपको एक बहुत ही नए कर्नेल की आवश्यकता होगी .... –

उत्तर

5

getrandom() syscall लिनक्स कर्नेल में पेश किया गया था 3.17। उबंटू 14.04 कर्नेल 3.13 के साथ भेज दिया जाता है, इसलिए आपको सिस्कोल प्राप्त करने के लिए एक और हालिया कर्नेल में अपडेट करना होगा।

उबंटू के लिए लिनक्स कर्नेल के .deb संकुल प्राप्त करने के लिए, kernel.ubuntu.com पर एक नज़र डालें। इस समस्या पर भी askubuntu.com पर चर्चा की गई थी।

+1

@anothertest: आप libc को भी अपडेट करना चाहते हैं। या कोशिश करें 'int r = syscall (SYS_getrandom, buf, l, o);' इसके बजाए। – alk

8

तो, ऐसा लगता है कि getrandom एक समारोह, बस एक सिस्कल नहीं है।

इसलिए इस की जरूरत है:

/* 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; 
} 
+1

क्या 'buf' प्रारंभ किया जाना चाहिए? मुझे लगता है कि 'syscall()' गलती को रोक देगा क्योंकि आप शून्य को संबोधित करने के लिए 5 बाइट लिखने के लिए कह रहे हैं। – Jamie

2

मैं अपने कार्यक्रम के साथ लगता है कि आप एक विभाजन गलती मिल जाएगा। निम्नलिखित कोड को काम करना चाहिए:

#include <iostream> 
#include <unistd.h> 
#include <sys/syscall.h> 
#include <linux/random.h> 

int main() { 
    unsigned long int s; 
    syscall(SYS_getrandom, &s, sizeof(unsigned long int), 0); 
    std::cout << "The seed is: " << s << "." << std::endl; 
} 
3

getrandom and getentropy were added to glibc in version 2.25। जुलाई 2017 तक, अधिकांश लिनक्स वितरण अभी तक इस संस्करण में अपडेट नहीं हुए हैं (उदा। डेबियन की सबसे हालिया रिलीज, जो अभी बाहर आई है, 2.24 है) लेकिन उन्हें जल्द ही चाहिए।

यहाँ कैसे यदि उपलब्ध हो glibc रैपर का उपयोग करें और कच्चे सिस्टम कॉल नहीं तो में वापस आने का है:

#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 

(जैसा कि अन्य उत्तर में बताया, यह भी सुनिश्चित करें कि आप कर्नेल 3.17 है के लिए आवश्यक है या नए। दोनों my_getentropy के ऊपर संस्करणों असफल हो जायेगी और ENOSYS करने के लिए errno सेट एक पुराने कर्नेल पर चलाते हैं।)

0

यहाँ, मैं कुछ कोड से पहले दिखाया गया है, और कीड़े को सही संकलित शामिल जीसीसी -v से मेरी उत्पादन होता है तुलना के लिए।

// $ gcc -v 
// Using built-in specs. 
// COLLECT_GCC=gcc 
// COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/5/lto-wrapper 
// Target: x86_64-linux-gnu 
// Configured with: ../src/configure -v --with-pkgversion='Ubuntu 
// 5.4.0-6ubuntu1~16.04.9' --with-bugurl=file:///usr/share/doc/gcc-5/README.Bugs 
// --enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr 
// --program-suffix=-5 --enable-shared --enable-linker-build-id 
// --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix 
// --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu 
// --enable-libstdcxx-debug --enable-libstdcxx-time=yes 
// --with-default-libstdcxx-abi=new --enable-gnu-unique-object 
// --disable-vtable-verify --enable-libmpx --enable-plugin --with-system-zlib 
// --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo 
// --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-5-amd64/jre --enable-java-home 
// --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-5-amd64 
// --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-5-amd64 
// --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar 
// --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 
// --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib 
// --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu 
// --host=x86_64-linux-gnu --target=x86_64-linux-gnu 
// Thread model: posix 
// gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.9) 

//#define _GNU_SOURCE 

#include <stdio.h> 

#include <unistd.h> 
#include <sys/syscall.h> 
#include <linux/random.h> 

int main (int arg, char **argv) 
{ 
    size_t length = 5; 
    unsigned char buf[length]; 
    int r = syscall(SYS_getrandom, buf, length, 0); 

    if (r != 0) 
    { 
    int iIter; 
    printf ("random %zu bytes = ",length); 
    for (iIter = 0 ; iIter < length-1 ; iIter++) 
    { 
     printf ("%02x:", buf[iIter]); 
    } 
    printf ("%02x\n", buf[iIter]); 
    } 
    else 
    { 
    perror ("syscall (SYS_getrandom, ...)"); 
    } 
    return 0; 
} 
संबंधित मुद्दे