Round Robin Scheduler in C - c

I need a bit of help with my round robin scheduler. It is meant to take external C files and place them in a queue while displaying their current state, and execute them through round robin scheduling. Here is what I have so far:
#include<pthread.h>
#include<stdio.h>
#include<string.h>
#include<unistd.h>
enum states {running, ready, waiting, idle};
struct process{
//command to run process
enum states state;
int id;
};
struct process procs[5];
int procSize = 5;
void *runProcess(struct process *p)
{
while(1)
{
printf("Process %i is running", p->id);
sleep(1);
}
}
void *takeInput(void *vargp)
{
//print process statuses when 'procs' is entered
while(1)
{
char *str[64];
fgets(str, 64, stdin);
if (strcmp(str, "procs"))
{
for (int i = 0; i < procSize; i++)
{
printf("Process %i: %i\n", procs[i].id, procs[i].state);
}
}
}
}
void *schedule(void *vargp)
{
struct process p = procs[0];
if (p.state == idle)
{
p.state = ready;
}
if (p.state == ready)
{
p.state = running;
pthread_t run;
pthread_create(&run, NULL, runProcess, &p);
//pthread_join(run, NULL);
sleep(5);
pthread_cancel(run);
p.state = ready;
for(int i = procSize - 1; i > 0; i--)
{
procs[i-1] = procs[i];
}
procs[procSize] = p;
}
else if (p.state == waiting)
{
for(int i = procSize - 1; i > 0; i--)
{
procs[i-1] = procs[i];
}
procs[procSize] = p;
}
}
int main()
{
for (int i = 0; i < 5; i++)
{
struct process p;
p.state = idle;
p.id = i;
procs[i] = p;
}
pthread_t schedulerid;
pthread_t inputid;
pthread_create(&schedulerid, NULL, schedule, NULL);
//pthread_join(schedulerid, NULL);
pthread_create(&inputid, NULL, takeInput, NULL);
//pthread_join(inputid, NULL);
}
When I attempt to run this, I get no errors, only warnings, and nothing happens. What do I need to improve on? Is there an issue with trying to call functions using threads? Any help is appreciated.
UPDATED WITH WARNINGS:
Sched.c:35:20: warning: passing argument 1 of ‘strcmp’ from incompatible pointer type [-Wincompatible-pointer-types]
35 | if (strcmp(str, "procs"))
| ^~~
| |
| char **
In file included from Sched.c:3:
/usr/include/string.h:137:32: note: expected ‘const char *’ but argument is of type ‘char **’
137 | extern int strcmp (const char *__s1, const char *__s2)
| ~~~~~~~~~~~~^~~~
Sched.c: In function ‘schedule’:
Sched.c:56:36: warning: passing argument 3 of ‘pthread_create’ from incompatible pointer type [-Wincompatible-pointer-types]
56 | pthread_create(&run, NULL, runProcess, &p);
| ^~~~~~~~~~
| |
| void * (*)(struct process *)
In file included from Sched.c:1:
/usr/include/pthread.h:200:15: note: expected ‘void * (*)(void *)’ but argument is of type ‘void * (*)(struct process *)’
200 | void *(*__start_routine) (void *),
| ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~

Lets fix those warnings
char *str[64];
fgets(str, 64, stdin);
if (strcmp(str, "procs"))
should be
char str[64];
fgets(str, 64, stdin);
if (strcmp(str, "procs"))
then
pthread_create(&run, NULL, runProcess, &p);
The function must be a void* func (void*)
So change run process to
void *runProcess(void *v)
{
struct process *p =(struct process*)v;
while(1)
{
printf("Process %i is running", p->id);
sleep(1);
}
}
ie pass a void * and cast it to what you need
this compiles with no warning now.
Finally put your joins back in
int pt1 = pthread_create(&schedulerid, NULL, schedule, NULL);
int pt2 = pthread_create(&inputid, NULL, takeInput, NULL);
printf("%d %d \n", pt1, pt2);
pthread_join(schedulerid, NULL);
pthread_join(inputid, NULL);
as a final note - you really must test the returns from all your system calls to make sure they worked
here it is running
pm100#paul-think:~/ut$ gcc ggg.c -g -lpthread
pm100#paul-think:~/ut$ ./a.out
Process 0 is running

Related

Warning in C that says "expected ‘char *’ but argument is of type ‘char **’"

Hello so I have a main fuction where I declare two strings, ask for 2 inputs and call a function that looks like the following, but i have warnings on readString and showF that say "expected ‘char *’ but argument is of type ‘char **’" and i cant understand why:
char *originCode;
char *destinationCode;
printf("Insert origin airport code: ");
readString(&originCode, 3);
printf("Insert destination airport code: ");
readString(&destinationCode, 3);
printf("\n");
showF(flights, &originCode, &destinationCode);
readString function code:
void readString(char *charArr, unsigned int maxChars) {
fgets(charArr, maxChars, stdin);
removeNewline(charArr); /* modifies in-place*/
}
showF function code:
void showF(PtList flights, char *originCode, char *destinationCode) {
if(flights != NULL && originCode != NULL && destinationCode != NULL) {
showFlightsWithRoute(flights, originCode, destinationCode);
}
}
showFlightsWithRoute code:
void showFlightsWithRoute(PtList flights, char *originCode, char *destinationCode) {
//create a new list
PtList list = listCreate();
//search flights for flights that have the same origin and destination as the ones we want and add them to the new list
int size;
listSize(flights, &size);
Flight flight;
for(int i = 0; i < size; i++) {
listGet(flights, i, &flight);
if(equalsStringIgnoreCase(flight.originAirport, originCode) == 1 && equalsStringIgnoreCase(flight.destinationAirport, destinationCode) == 1)
listAdd(list, i, flight);
}
//print information about the flights
int newListSize;
listSize(list, &newListSize);
Flight elem;
if(newListSize == 0) {
printf("Flight data not available for route <%s> ==> <%s>", originCode, destinationCode);
}
else {
printf("----------------------------------Flights With Desired Route----------------------------------\n");
for(int i = 0; i < size; i++) {
listGet(list, i, &elem);
flightPrint(&elem);
printf("\n");
}
}
}
The problem is that you send char** in functions taking as a parameter a char*.
Here is your main :
char *originCode;
char *destinationCode;
printf("Insert origin airport code: ");
readString(&originCode, 3); //needs char*
printf("Insert destination airport code: ");
readString(&destinationCode, 3); //needs char*
printf("\n");
showF(flights, &originCode, &destinationCode); //needs char*
The function readString takes a char*, not a char**, so when you call it, you have to call it this way :
readString(originCode, 3); //no & before originCode or it sends a char**
...
readString(originCode, 3); //same comment than above
It is the same issue with showF : you are sending a char** because you are using & :
showF(flights, &originCode, &destinationCode); //wrong
showF(flights, originCode, destinationCode); //right

Producers and Consumers with semaphores and threads

I am currently having issues this code. The only part of the code that is having error is "io_production_report(thread_args[0].Produced, pointer);".
The terminal mentions the error as follows"
driver.cpp: In function ‘int main(int, char**)’:
driver.cpp:83:51: error: cannot convert ‘int (*)[2]’ to ‘int**’
83 | io_production_report(thread_args[0].Produced, pointer);
| ^~~~~~~
| |
| int (*)[2]
In file included from driver.cpp:2:
io.h:49:48: note: initializing argument 2 of ‘void io_production_report(int*, int**)’
49 | void io_production_report(int produced[], int *consumed[]);
| ~~~~~^~~~~~~~~~
make: *** [Makefile:8: driver.o] Error 1
I am having problems implementing an array of pointers.
If anyone can help me that would be great!! :
driver.cpp
// Print Production Report
int pointer[2][2];
pointer[0][0]=thread_args[0].Consumed[0]; //Ethel
pointer[0][1]=thread_args[0].Consumed[1]; //Lucy
pointer[1][0]=thread_args[1].Consumed[0];
pointer[1][1]=thread_args[1].Consumed[1];
io_production_report(thread_args[0].Produced, pointer); //NEED HELP ON THIS LINE
driver.h
struct args {
sem_t *mutexOnBelt;
sem_t *frogMax;
sem_t *beltMax;
sem_t *candiesOnBelt;
sem_t *produceMax;
sem_t *consumeMax;
string *belt;
int *head;
int *tail;
int wait_time;
int produced;
string *name;
int Consumed[2];
int onBelt[2];
int Produced[2];
};
int option = 0;
int flagValues[4] = {0, 0, 0, 0};
io.c
/*
* void io_production_report(int produced[], int *consumed[])
* Show how many candies of each type produced. Show how many candies consumed by
* each consumer.
* produced[] - count for each ProductType
* *consumed[] - array of pointers to consumed arrays
* e.g. consumed[Lucy] points to an array that is indexed by product name
*/
void io_production_report(int produced[], int *consumed[]) {
int p, c; /* array indices */
int total;
printf("\nPRODUCTION REPORT\n----------------------------------------\n");
/* show number produced for each producer / candy type */
for (p=0; p < ProductTypeN; p++) {
printf("%s producer generated %d candies\n",
ProducerNames[p], produced[p]);
}
/* show number consumed by each consumer */
for (c=0; c < ConsumerTypeN; c++) {
printf("%s consumed ", ConsumerNames[c]);
total = 0;
for (p=0; p < ProductTypeN; p++) {
if (p > 0)
printf(" + ");
total += consumed[c][p];
printf("%d %s", consumed[c][p], ProducerAbbrevs[p]);
}
printf(" = %d total\n", total);
}
printf("Elapsed time %.3f s\n", elapsed_s());
}
As explained in the comments you need to make a pointer to the first element of your array, id est: you specify you array[N][M] as int (*)[M], working example:
#include <stdio.h>
void io_production_report(int (*)[2]);
void io_production_report(int (*consumed)[2]) {
for (int i = 0; i <4; i++)
printf("%d\n", consumed[i/2][i%2]);
}
int main(void) {
int pointer[2][2];
pointer[0][0]=1; //Ethel
pointer[0][1]=2; //Lucy
pointer[1][0]=3;
pointer[1][1]=4;
io_production_report(pointer);
}

malloc() is returning the same address multiple times, even when I haven't used free()

EDIT: I did use free(), ignore the title.
The gist is that every time malloc() is called, the address 0x8403620
is returned, which I found out using Gdb.
tellers[i] = create_teller(0, i, NULL);
I first use malloc() on line 72 to create 3 teller structures. The first addressed returned, visible through Gdb, is 0x84003620. The second is
0x84033a0, the third 0x84034e0. Everything seems fine.
clients[i] = create_client(0, i, -1, -1);
Then I use malloc() on line 77 with the create_client() function to
create 100 clients. The first address, assigned to client[0], is ...
0x8403620. The same as tellers[0]. It gets worse. The next address
returned from malloc() is 0x8403620 again for when i = 1, and so
on for i = 3, 4, ..., 99.
It isn't inherently the create_client() or the create_teller() functions, but
instead the malloc() function itself.
This is simply a very odd situation.
Now, I'd like to ask: Am I using malloc() wrong? Or is my version of malloc() bugged and should I somehow reinstall whatever it is? It's most likely my code since it works for creating the tellers, just not for the clients.
Here is the full code:
#include <pthread.h>
#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <time.h>
#include <assert.h>
typedef struct teller teller_t;
typedef struct client client_t;
teller_t * create_teller (pthread_t thread_id, int id, client_t *assigned_client);
client_t * create_client (pthread_t thread_id, int id, int operation, int amount);
void * run_teller (void *arg);
void * run_client (void *arg);
/* types of operations */
#define DEPOSIT 0
#define WITHDRAW 1
#define NUM_TELLERS 3
#define NUM_CLIENTS 100
struct client {
pthread_t thread_id;
int id;
int operation;
int amount;
};
struct teller {
pthread_t thread_id;
int id;
bool available;
client_t *assigned_client;
};
client_t *clients[100];
teller_t *tellers[3];
/* only 2 tellers at a time can access */
sem_t safe;
/* only 1 teller at a time can access */
sem_t manager;
/* amount of tellers available, at most 3 */
sem_t line; /* rename to available? */
/* each teller waiting for a client to be assigned to them */
sem_t wait_for_client[3];
int
main (int argc, char **argv) {
(void) argc;
(void) argv;
srand(time(NULL));
/* This also tells us how many clients have been served */
int client_index = 0;
sem_init(&safe, 0, 2);
sem_init(&manager, 0, 1);
sem_init(&line, 0, 0);
for (int i = 0; i < 3; i++)
sem_init(&wait_for_client[i], 0, 0);
for (int i = 0; i < NUM_TELLERS; i++) {
tellers[i] = create_teller(0, i, NULL);
pthread_create(&tellers[i]->thread_id, NULL, run_teller, (void *) tellers[i]);
}
for (int i = 0; i < NUM_CLIENTS; i++) {
clients[i] = create_client(0, i, -1, -1);
pthread_create(&clients[i]->thread_id, NULL, run_client, (void *) clients[i]);
}
/* DEBUG
for (int i = 0; i < NUM_CLIENTS; i++) {
printf("client %d has id %d\n", i, clients[i]->id);
}
*/
// No threads should get past this point!!!
// ==------------------------------------==
// Should all of this below be handled by the clients instead of main?
while (1) {
if (client_index >= NUM_CLIENTS) {
// TODO:
// tell tellers that there are no more clients
// so they should close, then then close the bank.
break;
}
sem_wait(&line);
for (int i = 0; i < 3; i++) {
if (tellers[i]->available) {
int client_id = clients[client_index]->id;
//printf("client_index = %d\n", client_index); // DEBUG
tellers[i]->assigned_client = clients[client_index++];
tellers[i]->available = false;
printf(
"Client %d goes to Teller %d\n",
client_id,
tellers[i]->id
);
sem_post(&wait_for_client[i]);
break;
}
}
//sem_post(&line); // Is this needed?
}
return EXIT_SUCCESS;
}
teller_t *
create_teller (pthread_t thread_id, int id, client_t *assigned_client) {
teller_t *t = (teller_t *) malloc(sizeof(teller_t));
if (t == NULL) {
printf("ERROR: Unable to allocate teller_t.\n");
exit(EXIT_FAILURE);
}
t->thread_id = thread_id;
t->id = id;
t->available = true;
t->assigned_client = assigned_client;
return t;
}
/* TODO: Malloc returns the same address everytime, fix this */
client_t *
create_client (pthread_t thread_id, int id, int operation, int amount) {
client_t *c = malloc(sizeof(client_t));
if (c == NULL) {
printf("ERROR: Unable to allocate client_t.\n");
exit(EXIT_FAILURE);
}
c->thread_id = thread_id;
c->id = id;
c->operation = operation;
c->amount = amount;
return c;
}
void *
run_teller (void *arg) {
teller_t *t = (teller_t *) arg;
printf("Teller %d is available\n", t->id);
while (1) {
/* tell the line that a teller is available */
sem_post(&line);
/* pass when the line assignes a client to this teller */
sem_wait(&wait_for_client[t->id]);
assert(t->assigned_client != NULL);
if (t->assigned_client->operation == WITHDRAW) {
}
else {
}
}
free(arg);
pthread_cancel(t->thread_id);
return NULL;
}
void *
run_client (void *arg) {
client_t *c = (client_t *) arg;
c->operation = rand() & 1;
printf(
"Client %d waits in line to make a %s\n",
c->id,
((c->operation == DEPOSIT) ? "Deposit" : "Withdraw")
);
free(arg);
pthread_cancel(c->thread_id);
return NULL;
}
Then I use malloc() on line 77 with the create_client() function to create 100 clients.
Not exactly, you create one object, then you spawn a thread that manages that object, run_client() and then repeat. But run_client() basically does nothing except free() your client object! So malloc is totally right returning the same address again, as it is now free memory.
It just happens that your client threads are faster than your main one. Your problem here is that you are freeing the objects from secondary threads while leaving the dangling pointers in the global pointer array. If you use that array for debugging purposes, then nothing is actually wrong here, but if you want to use the client objects somewhen in the future, then you should not free your clients in the first place.

Unexpected Segmentation Fault in pthread Program

So a foreword, I am new to C, so please forgive any horrifying mistakes my program has.
I am trying to write a program that will take a list of numbers passed in as arguments to the program or contained in a file whose path is passed in.
It stores the numbers into an array, and stores how many numbers there are into the first element of the array. It will only store up to 100 numbers.
It then creates a pthread and passes the pointer to the array to the thread.
The thread is then suppose to sum up the numbers and return the sum back to the main function.
I am experiencing the following issues:
1. It doesn't always happen, but sometimes I get a segmentation fault right before the line of code that says:
printf("Begining to create the thread");
2. My attempts to return the sum isn't working, and after hours of research online, I can't figure out why.
3. When I compile the program, I get the following errors:
gcc -g -o assn3 assn3.c -pthread
assn3.c: In function ‘AddUpNumbers’:
assn3.c:34:9: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
return (void*)total;
^
assn3.c: In function ‘main’:
assn3.c:96:3: warning: passing argument 1 of ‘pthread_join’ makes integer from pointer without a cast [enabled by default]
pthread_join(&functionThread, &total);
^
In file included from assn3.c:12:0:
/usr/include/pthread.h:261:12: note: expected ‘pthread_t’ but argument is of type ‘pthread_t *’
extern int pthread_join (pthread_t __th, void **__thread_return);
^
assn3.c:97:3: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘void *’ [-Wformat=]
printf("The total returned by the thread is %d", total);
^
Here's my code:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define NO_ARGS 1
#define ONLY_SINGLE_ARG 2
#define PATH_TO_READ_FROM 1
#define MAX_NUMBERS 101
#define MAX_CHAR_INPUT 255
#define COUNT_LOCATION 0
void* AddUpNumbers(void* arrayPointer) {
printf("Created the pthread!");
int* numbersArray = (int*)arrayPointer;
int count = numbersArray[COUNT_LOCATION];
int total = 0;
int i = 1;
while (i < count) {
total = total + numbersArray[i];
}
printf("The total to be returned is %d", total);
return (void*)total;
}
int main(int argc, char* argv[]) {
FILE * numbersFile = NULL;
int count = 0;
int numberArray[MAX_NUMBERS];
//Initialize the Array
int i = 0;
while (i < MAX_NUMBERS) {
numberArray[i] = 0;
i = i + 1;
}
if (argc == NO_ARGS) {
printf("Usage: # or file path, #, #, ..., #\n");
} else if (argc == ONLY_SINGLE_ARG) {
numbersFile = fopen(argv[PATH_TO_READ_FROM], "r");
if (numbersFile != NULL) {
char buff[MAX_CHAR_INPUT];
i = 1;
count = 0;
while (i < MAX_NUMBERS) {
if (fscanf(numbersFile, "%s", buff) != EOF) {
numberArray[i] = atoi(buff);
printf("%d\n", numberArray[i]);
i = i + 1;
count = count + 1;
} else {
break;
}
}
numberArray[COUNT_LOCATION] = count;
printf("Count Total: %d\n", numberArray[COUNT_LOCATION]);
} else {
printf("Error: Could not open file!\n");
return -1;
}
} else if (argc < MAX_NUMBERS + 1) {
i = 1;
count = 0;
while (i < argc) {
numberArray[i] = atoi(argv[i]);
printf("%d\n", numberArray[i]);
i = i + 1;
count = count + 1;
}
printf("See if error happens after this");
numberArray[COUNT_LOCATION] = count;
printf("Count Total: %d\n", numberArray[COUNT_LOCATION]);
} else {
printf("Too many numbers! This program can only add up to: %d numbers.\n", MAX_NUMBERS);
return -1;
}
printf("Begining to create the thread");
pthread_t functionThread;
int creationSuccess = 0;
void* total;
creationSuccess = pthread_create(&functionThread, NULL, AddUpNumbers, (void*)numberArray);
if (creationSuccess == 0) {
pthread_join(&functionThread, total);
printf("The total returned by the thread is %d", *((int)total));
} else {
printf("Something went wrong.\n");
}
if (numbersFile != NULL) {
fclose(numbersFile);
}
return 0;
}
My Makefile looks like this:
assn3: assn3.c
gcc -g -o assn3 assn3.c -pthread
You should be very wary of compiler warnings. Either clean them up or understand very well why they are ok. Pay special attention to warnings about data type mismatches.
In this case this warning probably explains the main problem:
In file included from assn3.c:12:0:
/usr/include/pthread.h:261:12: note: expected ‘pthread_t’ but argument is of type ‘pthread_t *’
extern int pthread_join (pthread_t __th, void **__thread_return);
^
You are (creating and) passing a pointer to your pthread_t object as the first argument of pthread_join(), but unlike pthread_create(), pthread_join() expects you to pass the pthread_t itself, not a pointer to it. All manner of havoc (technically, "undefined behavior") will ensue.
UPDATE: Additionally, the second argument you are passing to pthread_join() is an uninitialized pointer to void. If pthread_create() tries to write anything where it points then who knows what happens (undefined behavior again). You are expected to pass a valid pointer to the location where the result is to be written. In this case, that would be &total.
The syntax of pthread_create is:
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, *(*start_routine) (void *), void *arg);
pthread_t - is id of thread. So create variable pthread_t id, or array of values if you have a lot of threads, like pthread_t id[THREAD_NUM];
Then your func will looks like:
pthread_create(&id[i], NULL, &functionThread, (void*)numberArray);
With pthread_join(&functionThread, total);
The same thing.
int pthread_join(pthread_t thread, void **value_ptr);
So you join must look like:
pthread_join(&id[i], total);

Error "implicit declaration" with proc_create_entry from proc_fs.h

I'm using Fedora 19 with the kernel of 3.11.6-200.fc19.x86_64
I had some errors when learning proc_fs.h
It seems that these codes can be normally compiled on Ubuntu 12.04, I just cannot figure out what's wrong with it on Fedora.
[root#frederick-pc Test]# make
make -C /lib/modules/3.11.6-200.fc19.x86_64/build M=/home/frederick/Documents/HW_2nd/Test modules
make[1]: Entering directory `/usr/src/kernels/3.11.6-200.fc19.x86_64'
CC [M] /home/frederick/Documents/HW_2nd/Test/rw_proc.o
/home/frederick/Documents/HW_2nd/Test/rw_proc.c: In function ‘rw_proc_init’:
/home/frederick/Documents/HW_2nd/Test/rw_proc.c:43:2: error: implicit declaration of function ‘proc_create_entry’ [-Werror=implicit-function-declaration]
p = proc_create_entry(PROCFS_NAME, 0644, NULL);
^
/home/frederick/Documents/HW_2nd/Test/rw_proc.c:43:4: warning: assignment makes pointer from integer without a cast [enabled by default]
p = proc_create_entry(PROCFS_NAME, 0644, NULL);
^
/home/frederick/Documents/HW_2nd/Test/rw_proc.c:51:3: error: dereferencing pointer to incomplete type
p->read_proc = procfile_read;
^
/home/frederick/Documents/HW_2nd/Test/rw_proc.c:52:3: error: dereferencing pointer to incomplete type
p->write_proc = procfile_write;
^
/home/frederick/Documents/HW_2nd/Test/rw_proc.c:54:3: error: dereferencing pointer to incomplete type
p->mode = S_IFREG | S_IRUGO;
^
/home/frederick/Documents/HW_2nd/Test/rw_proc.c:55:3: error: dereferencing pointer to incomplete type
p->uid = 0;
^
/home/frederick/Documents/HW_2nd/Test/rw_proc.c:56:3: error: dereferencing pointer to incomplete type
p->gid = 0;
^
/home/frederick/Documents/HW_2nd/Test/rw_proc.c:57:3: error: dereferencing pointer to incomplete type
p->size = 37;
^
cc1: some warnings being treated as errors
make[2]: *** [/home/frederick/Documents/HW_2nd/Test/rw_proc.o] Error 1
make[1]: *** [_module_/home/frederick/Documents/HW_2nd/Test] Error 2
make[1]: Leaving directory `/usr/src/kernels/3.11.6-200.fc19.x86_64'
make: *** [default] Error 2
here're my codes
rw_proc.c
#include<linux/module.h>
#include<linux/kernel.h>
#include<linux/proc_fs.h>
#include<asm/uaccess.h>
#define PROCFS_MAX_SIZE 1024
#define PROCFS_NAME "my_procfile_1k"
MODULE_LICENSE("GPL");
static struct proc_dir_entry *p = NULL;
static char procfs_buffer[PROCFS_MAX_SIZE];
static unsigned long procfs_buffer_size = 0;
static int procfile_read(char *buffer,char **buffer_location,off_t offset, int buffer_length, int *eof,void *data)
{
int ret;
printk(KERN_INFO "procfile_read (/proc/%s) called\n", PROCFS_NAME);
if (offset > 0)
{
ret = 0;
}
else
{
memcpy(buffer, procfs_buffer, procfs_buffer_size);
ret = procfs_buffer_size;
}
return ret;
}
static int procfile_write(struct file *file, const char *buffer, unsigned long count,void *data)
{
procfs_buffer_size = count;
if (procfs_buffer_size > PROCFS_MAX_SIZE ) {
procfs_buffer_size = PROCFS_MAX_SIZE;
}
if ( copy_from_user(procfs_buffer, buffer, procfs_buffer_size) ) {
return EFAULT;
}
return procfs_buffer_size;
}
static int rw_proc_init(void)
{
p = proc_create_entry(PROCFS_NAME, 0644, NULL);
if (p == NULL)
{
remove_proc_entry(PROCFS_NAME, NULL);
printk(KERN_ALERT "Error: Could not initialize /proc/%s\n",
PROCFS_NAME);
return ENOMEM;
}
p->read_proc = procfile_read;
p->write_proc = procfile_write;
//p->owner = THIS_MODULE;
p->mode = S_IFREG | S_IRUGO;
p->uid = 0;
p->gid = 0;
p->size = 37;
printk(KERN_INFO "/proc/%s created\n", PROCFS_NAME);
return 0;
}
static void rw_proc_exit(void)
{
remove_proc_entry(PROCFS_NAME, NULL);
printk(KERN_INFO "/proc/%s removed\n", PROCFS_NAME);
}
module_init(rw_proc_init);
module_exit(rw_proc_exit);
Who can help me? THX
Well finally i resolved the problem myself
it seems that since the version of 3.10.0, the function of proc_create_entry() has been deleted and replaced by proc_create()
so just replace them in the codes if you're compiling with a kernel newer than 3.10.0
Your variable p is not declared, this is what the compiler is trying to tell you. You'd just have to declare the variable locally at the beginning of the function like that:
struct proc_dir_entry *p = proc_create_entry(PROCFS_NAME, 0644, NULL);
(if struct proc_dir_entry* is really the type that the function returns, I didn't check.)

Resources