Malloc function shows error - malloc

`struct node * createLL(struct node *head)
{
int num;
struct node *new_node;
printf("enter the numbers you want to insert:\n");
printf("enter -1 to quit");
scanf("%d",&num);
while(num!=-1)
{
new_node=(struct node *) malloc (sizeof(struct node *));
new_node->data=num;
if(head==NULL)
{
new_node->next=NULL;
head=new_node;
}
else
{
new_node->next=head;
head=new_node;
}
printf("enter the numbers you want to insert:\n");
printf("enter -1 to quit");
scanf("%d",&num);
}
return head;
}`
the malloc used to create a new_node for the linked list of type struct node* is showing error. it says "malloc is not declared within scope"..
i referred books too..the code is same.. couldnot figure out how the error
can be corrected.

Are you sure you included the correct library in the header? Make sure you included
#include <stdlib.h>

Related

c: using strcpy() on an element inside a data structure

i am currently learning cs50. i am currently studying data structures..i came across a problem...please see if you could help:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct node{
char *name;
int age;
};
typedef struct node node;
int main(){
node *p=malloc(sizeof(node));
if (p==NULL){
return 1;
}
p->name="hussein";
p->age=32;
printf("staff1: %s, %d\n", p->name, p->age); //why doesn't this line of code work? program crashes here
strcpy(p->name, "hasan");
printf("staff1: %s, %d\n", p->name, p->age);
free(p);
return 0;
}
Use p->name = "hasan"; instead of strcpy(p->name, "hasan");.
The name in struct node is a pointer which can point to an array of char.
It didn't have allocated memory space for the char array.

Shared Memory giving ambiguous results

I was trying to communicate between two processes using Shared Memory concept. But here, though I have pointed the shared memory addresses of different variables to different files, they seem to be connected. As soon as I alter value of one variable, the new value overwrites on other variable too, in this case, se1->val and se2->val are coming out to be connected. Can someone help why it's happening so?
#include<stdio.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<unistd.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#define s(t) scanf("%d",&t)
#define p(t) printf("%d ",t)
struct sem
{
int val;
int xy;
};
struct sem* se1;
struct sem* se2;
int main()
{
printf("You in P1\n");
key_t key1,key2;
key1=ftok("shmfile1",0);
key2=ftok("shmfile3",0);
int shmid1=shmget(key1, sizeof(struct sem),0644|IPC_CREAT);
int shmid2=shmget(key2, sizeof(struct sem),0644|IPC_CREAT);
se1=shmat(shmid1,NULL,0);
se2=shmat(shmid2,NULL,0);
se1->xy=4;
se2->xy=8;
se1->val=0;
se2->val=1;
int r=10;
while(r--)
{
printf("\nIn P1 process ");
while(se2->val==0);
se2->val--;
se1->xy=se2->xy+1;
se1->val++;
p(se1->xy);
p(se2->xy);
}
return 0;
}
It is expected se1->val and se2->val will lead to semaphore type results, but due to overwriting it's not happening!

Please help me to make this fake character linux device driver work

Hello I am trying to write to a fake char device driver using:
echo > /dev/
and reading it using:
cat /dev/
My problem is that I am getting continuously the first character written printed on the terminal when I do a read with the above mentioned "cat" read method after writing using the echo method above.
My aim is to get the entire set of characters written to the driver back...
I am using dynamic memory allocation for this purpose but not getting the final result after trying many ways of rewriting the code of read() and write() in the driver. Please help..
my Makefile is correct... (I am using ubuntu with a kernel version of 2.6.33...)
My code is as below:
#include <linux/module.h>
#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/kdev_t.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/cdev.h>
#include <linux/uaccess.h>
static dev_t first;
static struct cdev c_dev;
static struct class *cl;
static char* k_buf = NULL;
static int my_open(struct inode *i,struct file *f)
{
printk(KERN_INFO "In driver open()\n");
return 0;
}
static int my_close(struct inode *i,struct file *f)
{
printk(KERN_INFO "In driver close()\n");
return 0;
}
static ssize_t my_read(struct file *f,char __user *buf,size_t len,loff_t *off)
{
printk(KERN_INFO "In driver read()\n");
if(k_buf == NULL)
{
printk(KERN_INFO "You cannot read before writing!\n");
return -1;
}
while(*k_buf != 'EOF')
{
if(copy_to_user(buf,k_buf,1))
return -EFAULT;
off++;
return 1;
}
return 0;
}
static ssize_t my_write(struct file *f,const char __user *buf,size_t len,loff_t *off)
{
printk(KERN_INFO "In driver write()\n");
k_buf = (char*) kmalloc(sizeof(len),GFP_KERNEL);
if(copy_from_user(k_buf,buf,len))
return -EFAULT;
off += len;
return (len);
}
static struct file_operations fops =
{
.owner = THIS_MODULE,
.open = my_open,
.release = my_close,
.read = my_read,
.write = my_write
};
static int __init rw_init(void) /*Constructor*/
{
printk(KERN_INFO "hello: rw_ch_driver registered\n");
if(alloc_chrdev_region(&first,0,1,"krishna") < 0)
{
return -1;
}
if ((cl = class_create(THIS_MODULE,"chardev")) == NULL)
{
unregister_chrdev_region(first,1);
return -1;
}
if (device_create(cl,NULL,first,NULL,"rw_char_driver") == NULL)
{
class_destroy(cl);
unregister_chrdev_region(first,1);
return -1;
}
cdev_init(&c_dev,&fops);
if(cdev_add(&c_dev,first,1) == -1)
{
device_destroy(cl,first);
class_destroy(cl);
unregister_chrdev_region(first,1);
return -1;
}
return 0;
}
static void __exit rw_exit(void)/*destructor*/
{
cdev_del(&c_dev);
device_destroy(cl,first);
class_destroy(cl);
unregister_chrdev_region(first,1);
printk(KERN_INFO "bye rw_chardriver unregistered");
}
module_init(rw_init);
module_exit(rw_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("krishna");
MODULE_DESCRIPTION("read write character driver");
Take a careful look at your while loop in my_read().
Most important note first: you don't need this loop. You've put a return statement in it, so it is never going to execute more than once, because the whole function is going to exit when the return is reached. It looks like you're trying to make the function return a single byte at a time repeatedly, but you should just call copy_to_user once, and pass it the number of bytes you want to give back to the user instead. If you only send one character at a time that's fine. It will be up to the user to make the read call again to get the next character.
The nice thing about copy_to_user, is that its return code will tell you if it failed because of bad array bounds, so there's no need to check for EOF on every character. In fact, you are not going to get 'EOF' as a character when you are reading from your buffer because it doesn't exist. Your buffer will store characters and usually a null terminator, '\0', but there is no 'EOF' character in C. EOF is a state you need to identify yourself and report to whoever called open. For the "cat" command, this is done by returning 0 from read. That being said, you should still check your array bounds so we don't end up with another Heartbleed. This SO answer has a good suggestion for how to do bounds checking to make sure you don't send more bytes than your buffer has.
Also, give [this post(https://meta.stackexchange.com/questions/981/syntax-highlighting-language-hints) a read. If you don't have your language in your question tags, it is helpful to other readers to tag your. I've edited your question to clean it up, so you can click "edit" now to see how I did it.

copy_to_user not working in kernel module

I was trying to use copy_to_user in kernel module read function, but am not able to copy the data from kernel to user buffer. Please can anyone tell me if I am doing some mistake. My kernel version is 2.6.35. I am giving the portion of kernel module as well as the application being used to test it. Right now my focus is why this copy_to_user is not working. Any help will great.
///////////////////////////////////kernel module//////////////////////////////////////
#define BUF_LEN 80
static char msg[BUF_LEN];
static char *msg_Ptr;
static int device_open(struct inode *inode, struct file *file)
{
static int counter = 0;
if (Device_Open)
return -EBUSY;
Device_Open++;
printk(KERN_ALERT "In open device call\n");
sprintf(msg, "I already told you %d times Hello world!\n", counter++);
msg_Ptr = msg;
try_module_get(THIS_MODULE);
return SUCCESS;
}
static ssize_t device_read(struct file *filp,
char __user *buffer,
size_t length,
loff_t * offset)
{
/*
* Number of bytes actually written to the buffer
*/
int bytes_read = 0;
/*
* If we are at the end of the message,
* return 0 signifying end of file
*/
if (*msg_Ptr == 0)
return 0;
/*
* Actually put the data into the buffer
*/
else {
bytes_read=copy_to_user(buffer, msg, length);
if (bytes_read==-1);
{
printk(KERN_INFO "Error in else while copying the data \n");
}
}
return bytes_read;
}
////////////////////////////////////////application////////////////////////
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#define BUF_SIZE 40
int main()
{
ssize_t num_bytes;
int fd, n=0;
char buf[BUF_SIZE];
fd=open("/dev/chardev", O_RDWR);
if(fd== -1){perror("Error while opening device");exit(1);}
printf("fd=%d\n",fd);
num_bytes=read(fd, buf, BUF_SIZE);
if(num_bytes==-1){perror("Error while reading"); exit(2);}
printf("The value fetched is %lu bytes\n", num_bytes);
while(n<=num_bytes)
{
printf("%c",buf[n]);
n++;
}
close(fd);
return 0;
}
There are a few problems in the code snippet you wrote. First of all, it is not a good thing to make the call try_module_get(THIS_MODULE);
This statement tries to increase the refcount of the module ... in the module itself ! Instead, you should set the owner field of the file_ops structure to THIS_MODULE in your init method. This way, the reference handling will happen outside the module code, in the VFS layer. You might take a look at Linux Kernel Modules: When to use try_module_get / module_put.
Then, as it was stated by Vineet you should retrieve the pointer from the file_ops private_data field.
And last but not least, here is the reason why it seems an error happened while ... Actually ... It did not :
The copy_to_user call returns 0 if it has successfully copied all the desired bytes into the destination memory area and a strictly positive value stating the number of bytes that were NOT copied in case of error. That said, when you run :
/* Kernel part */
bytes_read=copy_to_user(buffer, msg, length);
/*
* Wrong error checking :
* In the below statement, "-1" is viewed as an unsigned long.
* With a simple equality test, this will not bother you
* But this is dangerous with other comparisons like "<" or ">"
* (unsigned long)(-1) is at least 2^32 - 1 so ...
*/
if (-1 == bytes_read) {
/* etc. */
}
return bytes_read;
/* App part */
num_bytes=read(fd, buf, BUF_SIZE);
/* etc.. */
while(n<=num_bytes) {
printf("%c",buf[n]);
n++;
}
You should only get one character upon a successful copy, that is only a single "I" in your case.
Moreover, you use your msg_Ptr pointer as a safeguard but you never update it. This might result in a wrong call to copy_to_user.
copy_to_user checks the user-space pointer with a call to access_ok, but if the kernel-space pointer and the given length are not allright, this might end in a Kernel Oops/Panic.
I think you should update the file->private_data in open and then you have to fetch that in your structure. Because I guess the msg buffer ( kernel buffer ) is not getting proper refernce.

pcap_findalldevs_ex function is undefined

I am trying out an example of obtaining advanced information about installed n/w devices from WinPcap.
I have even followed the instructions for including WinPcap library ,still the compiler complains that pcap_findalldevs_ex is undefined
at line if (pcap_findalldevs_ex(source, NULL, &alldevs, errbuf) == -1).
My Code :
#include "stdafx.h"
#include <stdio.h>
#include "pcap.h"
#include <winsock2.h>
#pragma comment(lib, "ws2_32")
// Function prototypes
void ifprint(pcap_if_t *d);
char *iptos(u_long in);
char* ip6tos(struct sockaddr *sockaddr, char *address, int addrlen);
int _tmain(int argc, _TCHAR* argv[])
{
pcap_if_t *alldevs;
pcap_if_t *d;
char errbuf[PCAP_ERRBUF_SIZE+1];
char source[PCAP_ERRBUF_SIZE+1];
printf("Enter the device you want to list:\n"
"rpcap:// ==> lists interfaces in the local machine\n"
"rpcap://hostname:port ==> lists interfaces in a remote machine\n"
" (rpcapd daemon must be up and running\n"
" and it must accept 'null' authentication)\n"
"file://foldername ==> lists all pcap files in the give folder\n\n"
"Enter your choice: ");
fgets(source, PCAP_ERRBUF_SIZE, stdin);
source[PCAP_ERRBUF_SIZE] = '\0';
/* Retrieve the interfaces list */
if (pcap_findalldevs_ex(source, NULL, &alldevs, errbuf) == -1)
{
fprintf(stderr,"Error in pcap_findalldevs: %s\n",errbuf);
exit(1);
}
/* Scan the list printing every entry */
for(d=alldevs;d;d=d->next)
{
ifprint(d);
}
pcap_freealldevs(alldevs);
return 1;
return 0;
}
/* Print all the available information on the given interface */
void ifprint(pcap_if_t *d)
{
//Code removed to reduce length and it contains no errors.
}
/* From tcptraceroute, convert a numeric IP address to a string */
#define IPTOSBUFFERS 12
char *iptos(u_long in)
{
//Code removed to reduce length
}
char* ip6tos(struct sockaddr *sockaddr, char *address, int addrlen)
{
//Code removed to reduce length
}
Can some one point me in the right direction?
Edit : If I use pcap_findalldevs(&alldevs, errbuf) in the above code it builds successfully. So I guess it has no problem linking to the dll.
Edit 1 : Error
error C3861: 'pcap_findalldevs_ex': identifier not found
IntelliSense:identifier "pcap_findalldevs_ex" is undefined
Thanks.
pcap_findalldevs_ex is only present if you define HAVE_REMOTE
Add HAVE_REMOTE as a preprocessor definition in project properties, or do the following for every include of pcap.h:
#define HAVE_REMOTE
#include "pcap.h"

Resources