2016-04-16 8 views
0

Ich muss curr_task->pid, ein pid_t im Kernel-Raum, zu einem Feld der Struktur im Benutzerraum kopieren, der Platz für eine lange hat. Da es sich um eine Erweiterung handelt, erwarte ich keine Probleme.Casting und das copy_to_user Makro

aber ich warnt ein lästiges Compiler bekommen (copy_long_to_user ist für alle Absichten und Zwecke der gleichen wie 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 *’ 

Ist diese Warnung etwas, das ich bedenkenlos ignorieren kann (wird der Compiler tun, um die Besetzung für mich)? Wenn ich explizit curr_task->pid zu einem Long casten muss, wie kann ich das im Zusammenhang mit der Verwendung von copy_to_user tun? Meine Vermutung wäre, dass es etwas wie ist: (copy_long_to_user(&info_array[num_filled_kernel].pid, &((long)curr_task->pid)))

+0

Ich hoffe, Sie hat nicht nur ein Teil von @ ChunleiMa Antwort und machen den Typ des zweiten Parameters von 'copy_long_to_user()' a 'void *'. –

+0

Nein, die Antwort ließ mich erkennen, was ich falsch gemacht hatte - ich sagte 'copy_to_user', um 8 Bytes zu kopieren, wenn nur 4 Bytes Daten am Quellort waren. – Adam

+0

Ich dachte, dass vielleicht eine Abkürzung wie ich erwähnt hätte, was Sie andere, verwandte Frage verursacht haben: http://stackoverflow.com/questions/36658863/printing-pid-with-d-vs-ld-linux –

Antwort

2

Im Linux-Kernel ist der Typ von pid_t gleich int. Daher warnt der Compiler Sie, dass int* nicht in long int* umgewandelt werden kann. Ich weiß nicht, wie Sie Ihre copy_long_to_user Funktion erkennen, wenn Sie so schreiben, können Sie ein falsches Ergebnis erhalten. copy_long_to_user(long int* dest, long int* src){ copy_to_user(dest, src, sizeof(long int)); ...... } weil sizeof(long)> = sizeof(int), wenn sizeof(long)>sizeof(int) unterstützen, dass sizeof(long) == 8 und sizeof(int) always 4 Sie ein falsches Ergebnis erhalten werden, weil current_task->pid nur das 4 Byte dest besetzen, aber copy_to_user(dest, src, sizeof(long int)) 8 Byte kopieren muss auf dest, so die 4 Bytes folgen die current->pid werden zu dest kopiert, so dest kann nicht gleich current->pid. so sollten Sie besser eine Funktion schreiben namens copy_pid_to_user und Codes wie folgt aus: copy_pid_to_user(long int* dest, void* src){ copy_to_user(dest, src, sizeof(curent->pid)) ......

4

Sie benötigen eine Hilfsvariable, um dies richtig zu tun.

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

Unter der Adresse eines Helfer Variable legal ist, die Adresse eines temporären (von der Besetzung produziert) nicht.