2016-04-16 2 views
0

Мне нужно скопировать curr_task->pid, a pid_t в пространство ядра, в поле структуры в пространстве пользователя, которое имеет место в течение длительного времени. Поскольку это расширяющееся преобразование, я не ожидаю никаких проблем.casting и copy_to_user macro

Однако я получаю раздражает предупреждение компилятора (copy_long_to_user для всех намерений и целей такой же, как copy_to_user):

cs300/process_ancestors.c:31:3: warning: passing argument 2 of ‘copy_long_to_user’ from incompatible pointer type [enabled by default] 
    if(copy_long_to_user(&info_array[num_filled_kernel].pid, &curr_task->pid)) {  
^
cs300/process_ancestors.c:9:5: note: expected ‘long int *’ but argument is of type ‘pid_t *’ 

Является ли это предупреждение, что я могу смело игнорировать (компилятор будет делать бросок для меня)? Если мне нужно наложить curr_task->pid на длительное время, как я могу это сделать в контексте использования copy_to_user? Я предполагаю, что это что-то вроде: (copy_long_to_user(&info_array[num_filled_kernel].pid, &((long)curr_task->pid)))

+0

Я надеюсь, что вы не просто принять участие @ ответ ChunleiMa и сделать тип второго параметра 'copy_long_to_user()' '' недействительным *. –

+0

Нет, ответ заставило меня понять, что я делаю неправильно, хотя я говорил «copy_to_user» копировать 8 байтов, когда в исходном местоположении было всего 4 байта данных. – Adam

+0

Я думал, что, возможно, ярлык, как я упоминал, может быть причиной того, что вы другой, связанный с ним вопрос: http://stackoverflow.com/questions/36658863/printing-pid-with-d-vs-ld-linux –

ответ

2

В ядре Linux тип pid_t равен int, поэтому компилятор предупреждает вас о том, что int* не может отличить от long int*. Я не знаю, как вы понимаете свою функцию copy_long_to_user, если вы пишете вот так, вы можете получить неправильный результат. copy_long_to_user(long int* dest, long int* src){ copy_to_user(dest, src, sizeof(long int)); ...... } потому sizeof(long)> = sizeof(int), если sizeof(long)>sizeof(int), подтверждают, что sizeof(long) == 8 и sizeof(int) always 4, вы получите неверный результат, потому что current_task->pid просто занимают 4 байта dest, но copy_to_user(dest, src, sizeof(long int)) должен скопировать 8 байт в Dest, так что 4 байты, следующие за current->pid, копируются в dest, поэтому dest не может быть равен current->pid. так что лучше написать функцию с именем copy_pid_to_user и он кодирует так: copy_pid_to_user(long int* dest, void* src){ copy_to_user(dest, src, sizeof(curent->pid)) ......

4

Для этого вам нужна вспомогательная переменная.

long curr_pid = curr_task->pid; 
copy_long_to_user(&info_array[num_filled_kernel].pid, &curr_pid); 

Принимая адрес вспомогательной переменной, является юридическим, адрес временного (созданного литой) не является.