ошибка: неявное объявление функции 'strtok_r'

Я новичок в программировании для Linux (Linux 3.7.10). Я попытался скомпилировать программу, которую я получил для github, но столкнулся с проблемами с ошибкой. Основная программа взята с ntop, откуда я скачал ndpi (https://svn.ntop.org/svn/ntop/trunk/nDPI/), и это скомпилировано нормально. Вторая часть — это фильтр режима ядра, который я получил с github (https://github.com/ewildgoose/ndpi-netfilter).

Во-первых, я не смог найти функцию strtok_r, объявленную ни в одном из заголовочных файлов. Я обыскал всю систему, это функция предварительной сборки в системе? Пожалуйста, любые указатели будут высоко оценены. Спасибо.

CC [M]  /home/mtot/ndpi/ndpi-netfilter/src/ndpi_cpy/lib/protocols/http.o
/home/mtot/ndpi/ndpi-netfilter/src/ndpi_cpy/lib/protocols/http.c: In function     'check_content_type_and_change_protocol':

/home/mtot/ndpi/ndpi-netfilter/src/ndpi_cpy/lib/protocols/http.c:610:4: error: implicit declaration of function 'strtok_r' [-Werror=implicit-function-declaration]

/home/mtot/ndpi/ndpi-netfilter/src/ndpi_cpy/lib/protocols/http.c:610:10: warning: assignment makes pointer from integer without a cast [enabled by default]

/home/mtot/ndpi/ndpi-netfilter/src/ndpi_cpy/lib/protocols/http.c:617:14: warning: assignment makes pointer from integer without a cast [enabled by default]

/home/mtot/ndpi/ndpi-netfilter/src/ndpi_cpy/lib/protocols/http.c:623:9: warning: assignment makes pointer from integer without a cast [enabled by default]

/home/mtot/ndpi/ndpi-netfilter/src/ndpi_cpy/lib/protocols/http.c:627:11: warning: assignment makes pointer from integer without a cast [enabled by default]

/home/mtot/ndpi/ndpi-netfilter/src/ndpi_cpy/lib/protocols/http.c:632:13: warning: assignment makes pointer from integer without a cast [enabled by default]

cc1: some warnings being treated as errors

make[2]: *** [/home/mtot/ndpi/ndpi-netfilter/src/ndpi_cpy/lib/protocols/http.o] Error 1

make[1]: *** [_module_/home/mtot/ndpi/ndpi-netfilter/src] Error 2

Добавление дополнительных деталей

Я нашел файл string.h с strtok_r в каталоге /usr/include. Что я сделал, так это добавил в файл http.c, а также -I/usr/include в ccflags-y в Makefile. Я получил следующие ошибки. Помощь очень нужна. Спасибо.

CC [M]  /home/mtot/ndpi/ndpi-netfilter/src/ndpi_cpy/lib/protocols/http.o
  In file included from include/linux/compiler.h:48:0,
                 from include/uapi/linux/stddef.h:1,
  `enter code here`               from include/linux/stddef.h:4,
                 from /usr/src/linux-3.7.10/include/uapi/linux/posix_types.h:4,
                 from include/uapi/linux/types.h:13,
                 from include/linux/types.h:5,
                 from include/uapi/linux/byteorder/little_endian.h:11,
                 from include/linux/byteorder/little_endian.h:4,
                 from /usr/src/linux-3.7.10/arch/x86/include/asm/byteorder.h:4,
                 from /home/mtot/ndpi/ndpi-netfilter/src/ndpi_cpy/include/ndpi_main.h:49,
                 from /home/mtot/ndpi/ndpi-netfilter/src/ndpi_cpy/include/ndpi_protocols.h:29,
                 from /home/mtot/ndpi/ndpi-netfilter/src/ndpi_cpy/lib/protocols/http.c:25:
include/linux/compiler-gcc.h:93:0: warning: "__attribute_const__" redefined [enabled by default]
In file included from /usr/include/features.h:375:0,
                 from /usr/include/string.h:25,
                 from /home/mtot/ndpi/ndpi-netfilter/src/ndpi_cpy/lib/protocols/http.c:24:
/usr/include/sys/cdefs.h:237:0: note: this is the location of the previous definition
In file included from include/linux/compiler.h:48:0,
                 from include/uapi/linux/stddef.h:1,
                 from include/linux/stddef.h:4,
                 from /usr/src/linux-3.7.10/include/uapi/linux/posix_types.h:4,
                 from include/uapi/linux/types.h:13,
                 from include/linux/types.h:5,
                 from include/uapi/linux/byteorder/little_endian.h:11,
                 from include/linux/byteorder/little_endian.h:4,
                 from /usr/src/linux-3.7.10/arch/x86/include/asm/byteorder.h:4,
                 from /home/mtot/ndpi/ndpi-netfilter/src/ndpi_cpy/include/ndpi_main.h:49,
                 from /home/mtot/ndpi/ndpi-netfilter/src/ndpi_cpy/include/ndpi_protocols.h:29,
                 from /home/mtot/ndpi/ndpi-netfilter/src/ndpi_cpy/lib/protocols/http.c:25:
include/linux/compiler-gcc.h:112:0: warning: "__always_inline" redefined [enabled by default]
In file included from /usr/include/features.h:375:0,
                 from /usr/include/string.h:25,
                 from /home/mtot/ndpi/ndpi-netfilter/src/ndpi_cpy/lib/protocols/http.c:24:
/usr/include/sys/cdefs.h:308:0: note: this is the location of the previous definition
In file included from include/linux/bitops.h:22:0,
                 from include/linux/kernel.h:10,
                 from include/linux/skbuff.h:17,
                 from include/linux/ip.h:20,
                 from /home/mtot/ndpi/ndpi-netfilter/src/ndpi_cpy/include/ndpi_main.h:105,
                 from /home/mtot/ndpi/ndpi-netfilter/src/ndpi_cpy/include/ndpi_protocols.h:29,
                 from /home/mtot/ndpi/ndpi-netfilter/src/ndpi_cpy/lib/protocols/http.c:25:
/usr/src/linux-3.7.10/arch/x86/include/asm/bitops.h:406:19: error: static declaration of 'ffs' follows non-static declaration
In file included from /usr/src/linux-3.7.10/arch/x86/include/asm/string.h:4:0,
                 from include/linux/string.h:17,
                 from include/linux/bitmap.h:8,
                 from include/linux/cpumask.h:11,
                 from /usr/src/linux-3.7.10/arch/x86/include/asm/cpumask.h:4,
                 from /usr/src/linux-3.7.10/arch/x86/include/asm/msr.h:18,
                 from /usr/src/linux-3.7.10/arch/x86/include/asm/processor.h:20,
                 from /usr/src/linux-3.7.10/arch/x86/include/asm/thread_info.h:22,
                 from include/linux/thread_info.h:54,
                 from include/linux/preempt.h:9,
                 from include/linux/spinlock.h:50,
                 from include/linux/mm_types.h:8,
                 from include/linux/kmemcheck.h:4,
                 from include/linux/skbuff.h:18,
                 from include/linux/ip.h:20,
                 from /home/mtot/ndpi/ndpi-netfilter/src/ndpi_cpy/include/ndpi_main.h:105,
                 from /home/mtot/ndpi/ndpi-netfilter/src/ndpi_cpy/include/ndpi_protocols.h:29,
                 from /home/mtot/ndpi/ndpi-netfilter/src/ndpi_cpy/lib/protocols/http.c:25:
/usr/src/linux-3.7.10/arch/x86/include/asm/string_64.h:64:5: error: expected identifier or '(' before '__extension__'
/usr/src/linux-3.7.10/arch/x86/include/asm/string_64.h:64:5: error: expected identifier or '(' before ')' token
In file included from include/linux/bitmap.h:8:0,
                 from include/linux/cpumask.h:11,
                 from /usr/src/linux-3.7.10/arch/x86/include/asm/cpumask.h:4,
                 from /usr/src/linux-3.7.10/arch/x86/include/asm/msr.h:18,
                 from /usr/src/linux-3.7.10/arch/x86/include/asm/processor.h:20,
                 from /usr/src/linux-3.7.10/arch/x86/include/asm/thread_info.h:22,
                 from include/linux/thread_info.h:54,
                 from include/linux/preempt.h:9,
                 from include/linux/spinlock.h:50,
                 from include/linux/mm_types.h:8,
                 from include/linux/kmemcheck.h:4,
                 from include/linux/skbuff.h:18,
                 from include/linux/ip.h:20,
                 from /home/mtot/ndpi/ndpi-netfilter/src/ndpi_cpy/include/ndpi_main.h:105,
                 from /home/mtot/ndpi/ndpi-netfilter/src/ndpi_cpy/include/ndpi_protocols.h:29,
                 from /home/mtot/ndpi/ndpi-netfilter/src/ndpi_cpy/lib/protocols/http.c:25:
include/linux/string.h:38:12: error: expected identifier or '(' before '__extension__'
include/linux/string.h:38:12: error: expected identifier or '(' before ')' token
include/linux/string.h:41:12: error: expected identifier or '(' before '__extension__'
include/linux/string.h:53:15: error: expected identifier or '(' before '__extension__'
include/linux/string.h:83:15: error: expected identifier or '(' before '__extension__'
include/linux/string.h:83:15: error: expected identifier or '(' before ')' token
include/linux/string.h:86:15: error: expected identifier or '(' before '__extension__'
include/linux/string.h:86:15: error: expected identifier or '(' before ')' token
include/linux/string.h:89:24: error: expected identifier or '(' before '__extension__'
include/linux/string.h:89:24: error: expected identifier or '(' before ')' token
include/linux/string.h:92:24: error: expected identifier or '(' before '__extension__'
include/linux/string.h:92:24: error: expected identifier or '(' before ')' token
make[2]: *** [/home/mtot/ndpi/ndpi-netfilter/src/ndpi_cpy/lib/protocols/http.o] Error 1
make[1]: *** [_module_/home/mtot/ndpi/ndpi-netfilter/src] Error 2
make[1]: Leaving directory `/usr/src/linux-3.7.10'
make: *** [all] Error 2

-----Создать файл

NDPI_PATH2 := ${NDPI_PATH}/src
NDPI_SRC := ndpi_cpy
NDPI_PRO := ${NDPI_SRC}/lib/protocols
NDPI_THIRD := $(NDPI_SRC)/lib/third_party/src
SYS_HDR := /usr/include

ccflags-y += -I${src}/${NDPI_SRC}/include -I${src}/${NDPI_SRC}/lib -I${src}/${NDPI_SRC}/lib/third_party/include -I${SYS_HDR} -DOPENDPI_NETFILTER_MODULE


EXTRA_CFLAGS := $(ccflags-y)

#MODULES_DIR := /lib/modules/$(shell uname -r)
#KERNEL_DIR := ${MODULES_DIR}/build

obj-m := xt_ndpi.o
xt_ndpi-y := main.o \
                ${NDPI_SRC}/lib/ndpi_main.o \
                ${NDPI_THIRD}/ahocorasick.o \
                ${NDPI_THIRD}/node.o \
                ${NDPI_THIRD}/sort.o \
                ${NDPI_PRO}/afp.o \
                ${NDPI_PRO}/http.o 


all:
        if test -d ${NDPI_SRC}; then \
                cp ${NDPI_PATH2}/* ${NDPI_SRC} -R; \
        else \
                mkdir ${NDPI_SRC}; \
                cp ${NDPI_PATH2}/* ${NDPI_SRC} -R; \
        fi
        make -C ${KERNEL_DIR} M=$$PWD;
        rm -r ${NDPI_SRC}
modules:
        make -C ${KERNEL_DIR} M=$$PWD $@;
modules_install:
        make -C ${KERNEL_DIR} M=$$PWD $@;
        depmod -a;
clean:
        make -C ${KERNEL_DIR} M=$$PWD $@;

person AlbertK    schedule 15.10.2013    source источник
comment
Какой дистрибутив Linux вы используете? (3.7.10 — это версия ядра; это бесполезно.) strtok_r не определяется стандартом C, хотя и определяется POSIX. В моей системе man strtok_r означает, что для его использования необходимо определить один из нескольких макросов тестирования функций.   -  person Keith Thompson    schedule 15.10.2013
comment
возможный дубликат Могу ли я использовать strtok() в модуле ядра Linux ?   -  person Keith Thompson    schedule 16.10.2013


Ответы (2)


strtok_r обычно находится в string.h. В системе Linux с установленными справочными страницами вы можете сделать

man strtok_r

и это даст страницу руководства:

STRTOK(3)                  Linux Programmer’s Manual                 STRTOK(3)

NAME
   strtok, strtok_r - extract tokens from strings

SYNOPSIS
   #include <string.h>

   char *strtok(char *str, const char *delim);

   char *strtok_r(char *str, const char *delim, char **saveptr);
...

Строка include говорит вам, в каком файле она находится (и должна быть включена в ваш код, который ее использует). Вы проверили, есть ли в вашей системе string.h? Обычно он ниже /usr/include.

Во многих дистрибутивах есть пакеты разработки. Вы устанавливали такие пакеты, чтобы получить полноценную среду разработки?

person Timothy Brown    schedule 15.10.2013
comment
В порядке. Я нашел string.h в /usr/include, и в нем определен strtok_r, но Makefile компилирует его для ядра linux/include. Строка.h не содержит определения для strtok_r. Любые идеи? Спасибо. - person AlbertK; 16.10.2013
comment
О, вы компилируете код ядра. Ядро — это совсем другая среда программирования, чем пользовательское пространство. Вполне возможно, что strtok_r просто нет в наличии. - person Keith Thompson; 16.10.2013
comment
Спасибо. Да, я пытаюсь скомпилировать загружаемый модуль ядра в среде netfilter (iptables). Во всяком случае, получить strtok_r без последующего взлома ядра. Спасибо еще раз. - person AlbertK; 16.10.2013

Тип

man strtok_r

в терминале. Вы должны получить справочную страницу вида strtok_r(3) (пожалуйста, перейдите по этой ссылке).

Убедитесь, что установлены соответствующие пакеты разработки и документации, такие как libc6-dev (или libc-dev), glibc-doc, manpages-dev. (Фактическое название зависит от дистрибутива).

person Basile Starynkevitch    schedule 15.10.2013