5

I'm trying to write a very simple piece of code for a class, but I'm just stumped as to why I can't compile it. Sorry if this is a duplicate or silly question, but I couldn't find any others that answered this for me. My full program is pasted below. When I try to compile, I get the following error:

test.c: In function 'main':

test.c:7:27: error: expected ';' before '{' token

Here's the code:

#include<stdio.h>
#include<linux/sched.h>
#include<linux/kernel.h>

int main(){
    struct task_struct *task;
    for_each_process(task){
        printf("I found task: %d\n", task->pid);
    }
    return 0;
}

I feel like I'm missing something painfully obvious, can anyone point out what the problem is here? I've tried initializing the 'task' object as NULL and using a simpler printf statement that just prints 'test', but nothing I've tried has fixed this compilation error.

Community
  • 1
  • 1
Ben
  • 139
  • 1
  • 2
  • 3
  • 1
    What is for_each_process? Is it a macro? – Vlad from Moscow Aug 24 '15 at 19:05
  • 1
    If it is a macro you should look through its definition that to determine how it is expanded. – Vlad from Moscow Aug 24 '15 at 19:07
  • Yes I believe it's a macro defined in include/linux/sched.h. The definition is: >#define for_each_process(p) > for (p = &init_task ; (p = next_task(p)) != &init_task ; ) – Ben Aug 24 '15 at 19:20
  • 1
    Odds are that this macro is only for use inside the kernel, so compiling this in a userspace program is futile. Set up a virtual machine for kernel hacking experiments. – Ulrich Eckhardt Aug 24 '15 at 19:25
  • Ah! You're right Ulrich, I believe the problem is I'm calling the macro outside the kernel. I'm already using a VM so no risk of messing up my system :-) I'll update once I can confirm it works from inside the kernel, in case anyone else is as bone-headed as I am. – Ben Aug 24 '15 at 19:40

2 Answers2

10

The macro has been moved to <linux/sched/signal.h> in this commit c3edc4010e9d102eb7b8f17d15c2ebc425fed63c in 2017. (https://github.com/torvalds/linux/commit/c3edc4010e9d102eb7b8f17d15c2ebc425fed63c).

(For someone who has trouble in compiling for this reason.)

Shuai
  • 962
  • 1
  • 10
  • 21
1

The preprocessor token you are using for_each_process is either not defined, or not defined to do what you think it does.

Every C++ compiler I've used can be told to dump the post-preprocessing output. If you pass the flag that makes this happen when building your source file, you'll see the code that the compiler is seeing and screwing up on.

gcc -E clang -E or the /E flag in visual studio (heh) for example.

As @Ulrich has mentioned above, apparently that macro is only available within the kernel. Attempting to read <linux/sched.h> directly and determine this is challenging, as there are many, many ifdef/endif pairs.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
  • 1
    As Ulrich pointed out above, the macro I was trying to use is only available inside the kernel. This is a kernel hacking assignment so I was just confused on that point, but thanks to everyone who helped. Rather than making a userspace program to call the macro, the intention was to make a syscall that could call the macro for you, then use the syscall from userspace. Hopefully this will help future confused students! – Ben Aug 24 '15 at 19:54