I am trying to write some data into the file line by line and then reading each data separatly line by line from the source file and writing it to another file.
But while writing data to destination file , I am getting spaces.
I mean the data is being written after multiple spaces.
I am using fgets instead of fread.
/*
* ======== fatsd.c ========
*/
#include <file.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <third_party/fatfs/ffcio.h>
#include <ti/display/Display.h>
#include <ti/drivers/GPIO.h>
#include <ti/drivers/SDFatFS.h>
#include <ti/drivers/UART.h>
/* Example/Board Header files */
#include "Board.h"
/* Buffer size used for the file copy process */
#ifndef CPY_BUFF_SIZE
#define CPY_BUFF_SIZE 2048
#endif
/* String conversion macro */
#define STR_(n) #n
#define STR(n) STR_(n)
/* Drive number used for FatFs */
#define DRIVE_NUM 0
int i= 20;
int x;
char con_buff[100];
const char inputfile[] = "fat:"STR(DRIVE_NUM)":input1.txt";
const char outputfile[] = "fat:"STR(DRIVE_NUM)":output.txt";
const char copyfile[] = "fat:"STR(DRIVE_NUM)":copy2.txt";
char textarray[] = "Jan 1 2017 00:00:00 75 822 96 548 85 76 82 93 78 82 64 89";
char text[]="ram sham heloo bye";
char cpy[]="\r\n";
static Display_Handle display;
/* File name prefix for this filesystem for use with TI C RTS */
char fatfsPrefix[] = "fat";
//unsigned char cpy_buff[CPY_BUFF_SIZE + 1];
char cpy_buff[CPY_BUFF_SIZE + 1];
char mybuff[CPY_BUFF_SIZE + 1];
/*
* ======== mainThread ========
* Thread to perform a file copy
*
* Thread tries to open an existing file inputfile[]. If the file doesn't
* exist, create one and write some known content into it.
* The contents of the inputfile[] are then copied to an output file
* outputfile[]. Once completed, the contents of the output file are
* printed onto the system console (stdout).
*/
void *mainThread(void *arg0)
{
SDFatFS_Handle sdfatfsHandle;
/* Variables for the CIO functions */
FILE *src, *dst,*new;
/* Variables to keep track of the file copy progress */
unsigned int bytesRead = 0;
unsigned int bytesWritten = 0;
unsigned int filesize;
unsigned int totalBytesCopied = 0;
/* Call driver init functions */
GPIO_init();
SDFatFS_init();
/* Configure the LED pin */
GPIO_setConfig(Board_GPIO_LED0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
/* add_device() should be called once and is used for all media types */
add_device(fatfsPrefix, _MSA, ffcio_open, ffcio_close, ffcio_read,
ffcio_write, ffcio_lseek, ffcio_unlink, ffcio_rename);
/* Turn on user LED */
GPIO_write(Board_GPIO_LED0, Board_GPIO_LED_ON);
strcpy(con_buff,"This example requires a FAT filesystem on the SD card.\r\n"
"You will get errors if your SD card is not formatted with a filesystem.\r\n");
puts(con_buff);
/* Mount and register the SD Card */
sdfatfsHandle = SDFatFS_open(Board_SDFatFS0, DRIVE_NUM);
if (sdfatfsHandle == NULL)
{
strcpy(con_buff,"Error starting the SD card\n");
puts(con_buff);
x=1;
while (1);
}
else
{
strcpy(con_buff,"Drive is mounted\n");
x=2;
}
/* Try to open the source file */
src = fopen(inputfile, "a");
if (!src)
{
strcpy(con_buff,"Creating a new file ...");
puts(con_buff);
x=3;
/* Open file for both reading and writing */
src = fopen(inputfile, "w+");
if (!src)
{
strcpy(con_buff,"Error:could not be created.\nPlease check the Board.html if additional jumpers are necessary.check if sd card is inserted correctly\n"
"Aborting... \n");
puts(con_buff);
x=4;
while (1);
}
x=5;
/* Reset the internal file pointer */
rewind(src);
}
else {
fseek(src, 0, SEEK_END);
filesize = ftell(src);
if(filesize!=0)
{
fwrite(cpy, 1, strlen(cpy), src);
}
fwrite(textarray, 1, strlen(textarray), src);
fwrite(cpy, 1, strlen(cpy), src);
fwrite(text, 1, strlen(text), src);
fwrite(cpy, 1, strlen(cpy), src);
fwrite(textarray, 1, strlen(textarray), src);
fwrite(cpy, 1, strlen(cpy), src);
fwrite(text, 1, strlen(text), src);
x=6;
}
fflush(src);
fclose(src);
/* Create a new file object for the file copy */
dst = fopen(outputfile, "w");
new = fopen(copyfile, "a");
src = fopen(inputfile, "r");
if(!new)
{
strcpy(con_buff,"Error opening new file ");
puts(con_buff);
}
if (!dst)
{
strcpy(con_buff,"Error opening \"%s\"\n"
"Aborting...\n");
puts(con_buff);
x=7;
while (1);
}
else {
strcpy(con_buff,"Starting file copy\n");
puts(con_buff);
x=8;
}
/* Copy the contents from the src to the dst */
while (!feof(src))
{
fgets(cpy_buff,sizeof(cpy_buff),src); //READ FROM FILE
/* Read from source file */
puts(cpy_buff);
i=i+1;
fwrite(cpy_buff, 1,sizeof(cpy_buff),dst); //PUBLISH
strcpy(cpy_buff,"\0");
}
fflush(dst);
/* Get the filesize of the source file */
fseek(src, 0, SEEK_END);
filesize = ftell(src);
sprintf(con_buff,"size of file is %d",filesize);
puts(con_buff);
/* Close both inputfile[] and outputfile[] */
fclose(src);
fclose(dst);
fclose(new);
sprintf(con_buff,"File \"%s\" (%u B) copied to \"%s\" (Wrote %u B)\n",inputfile, filesize, outputfile, totalBytesCopied);
puts(con_buff);
/* Now output the outputfile[] contents onto the console */
/* Stopping the SDCard */
SDFatFS_close(sdfatfsHandle);
sprintf(con_buff,"Drive %u unmounted\n", DRIVE_NUM);
puts(con_buff);
return (NULL);
}
/*
* ======== fatfs_getFatTime ========
*/
int32_t fatfs_getFatTime(void)
{
/*
* FatFs uses this API to get the current time in FatTime format. User's
* must implement this function based on their system's timekeeping
* mechanism. See FatFs documentation for details on FatTime format.
*/
/* Jan 1 2017 00:00:00 */
return (0x4A210000);
}
regarding statements like:
fwrite(cpy_buff, 1,sizeof(cpy_buff),dst);
This will write the whole buffer, even though most of the trailing bytes of the buffer cpy_buff are garbage. Suggest:
fwrite(cpy_buff, 1,strlen(cpy_buff),dst);
Related
I'm trying to send .amr files from my desktop to a SIM900 GSM module over UART.
I'm using teuniz's RS232 library.
I do the initialisation using AT commands and then read the file into a buffer and write it to the UART using the RS232_SendByte() library function byte-by-byte, but it doesn't seem to work.
I send the following AT commands:
AT+CFSINIT
AT+CFSWFILE=\"audio.amr\",0,6694,13000 # After which I get the CONNECT message from the SIM900 module
# Here's where I send the file
AT+CFSGFIS=\"audio.amr\"
Here's my code:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include "rs232.h"
char *readFile(char *filename, int *size) {
char *source = NULL;
FILE *fp = fopen(filename, "rb");
if (fp != NULL) {
/* Go to the end of the file. */
if (fseek(fp, 0L, SEEK_END) == 0) {
/* Get the size of the file. */
long bufsize = ftell(fp);
if (bufsize == -1) { return NULL; }
/* Allocate our buffer to that size. */
source = malloc(sizeof(char) * (bufsize + 1));
if(!source) return NULL;
/* Go back to the start of the file. */
if (fseek(fp, 0L, SEEK_SET) != 0) { return NULL; }
/* Read the entire file into memory. */
size_t newLen = fread(source, sizeof(char), bufsize, fp);
if ( ferror( fp ) != 0 ) {
fputs("Error reading file", stderr);
free(source);
return NULL;
} else {
source[newLen++] = 0; /* Just to be safe. */
}
*size = bufsize;
}
fclose(fp);
}
return source;
}
int main(int argc, char *argv[])
{
int ret = 0, cport_nr = 2, bdrate=38400;
char data[2000] = {0};
if(RS232_OpenComport(cport_nr, bdrate)) {
printf("Can not open comport\n");
ret = -1;
goto END;
}
int size;
unsigned char *filebuf = readFile("audio.amr", &size);
if (!filebuf) {
ret = -1;
goto END_1;
}
/* Initialization */
RS232_cputs(cport_nr, "AT");
RS232_cputs(cport_nr, "AT+CFSINIT");
sleep(1);
RS232_cputs(cport_nr, "AT+CFSWFILE=\"audio.amr\",0,6694,13000");
/* Wait for CONNECT */
sleep(2);
printf("Sending file of size: %d\n", size);
int i;
for (i = 0; i < size; ++i) {
putchar(filebuf[i]);
RS232_SendByte(cport_nr, filebuf[i]);
}
free(filebuf);
sleep(1);
/* Check if file transferred right */
RS232_cputs(cport_nr, "AT+CFSGFIS=\"audio.amr\"");
END_1:
RS232_CloseComport(cport_nr);
END:
return ret;
}
EDIT 1
Normally, the procedure to send a file to SIM900 using AT commands would be as documented here:
AT+CFSINIT # Initialize flash; Response is OK
AT+CFSWFILE=<filename>,<writeMode>,<fileSize>,<InputTime> # Write file with these parameter; Response is CONNECT; So this is when I start sending the file
Here's where I send the file. If it worked and the sent file size matched the <filesize> sent in the above command, SIM900 must respond with OK, which it doesn't. :(
AT+CFSGFIS=<filename> # Gives the file size on flash. This gives me an error since the file didn't upload correctly.
This leads me to beleive there's something wrong with my program. I'm reading the file in binary mode. And the size reported is exacty the same as I specify in the AT+CFSWFILE=<filename>,<writeMode>,<fileSize>,<InputTime> command.
On Ubuntu Linux I have written a c program based on the Libao example program to open audio wave file and play. It works fine but at the end after finish playing there is crackling high pitch noise. Here is the code which I modified mt libao example. How can I fix it? Please help
#include <stdio.h>
#include <string.h>
#include <ao/ao.h>
#include <math.h>
#define BUF_SIZE 4096
int main(int argc, char **argv)
{
ao_device *device;
ao_sample_format format;
int default_driver;
char *buffer;
int buf_size;
int sample;
FILE *fp;
float freq = 440.0;
int i;
/* -- Initialize -- */
fprintf(stderr, "libao example program\n");
ao_initialize();
/* -- Setup for default driver -- */
default_driver = ao_default_driver_id();
memset(&format, 0, sizeof(format));
format.bits = 16;
format.channels = 2;
format.rate = 44100;
format.byte_format = AO_FMT_LITTLE;
/* -- Open driver -- */
// device = ao_open_live(default_driver, &format, NULL /* no options */);
device = ao_open_live(default_driver, &format, NULL /* no options */);
if (device == NULL) {
fprintf(stderr, "Error opening device.\n");
return 1;
}
fp = fopen("nc.wav", "rb");
if (fp == NULL) {
fprintf(stderr, "Unable to open file \n");
return;
}
fseek(fp, 0, SEEK_END);
unsigned long fileLen = ftell(fp);
fseek(fp, 0, SEEK_SET);
//Allocate memory
buffer=(char *)malloc(fileLen+1);
if (!buffer)
{
fprintf(stderr, "Memory error!");
fclose(fp);
return;
}
fread(buffer, fileLen, 1, fp);
fclose(fp);
ao_play(device, buffer, buf_size);
/* -- Close and shutdown -- */
ao_close(device);
ao_shutdown();
return (0);
}
The buf_size variable is passed to ao_play without being initialized, and the crackles most likely occur because it is playing past the end of the sample buffer into random memory.
Depending on your compiler settings, the compiler can warn you about uninitialized variables bugs like this (gcc only does it when optimizations are turned on, via the -Wuninitialized or -Wall settings).
I am writing a character device that will be given a processes pid and return the parent process id, start time, and number of siblings. I am using this site: http://tldp.org/LDP/lkmpg/2.6/html/x892.html#AEN972 as a guide.
I would like to add an argument into the read call of the character driver but it is not letting me do that. My code looks like this:
/*
* chardev.c - Create an input/output character device
*/
#include <linux/kernel.h> /* We're doing kernel work */
#include <linux/module.h> /* Specifically, a module */
#include <linux/fs.h>
#include <asm/uaccess.h> /* for get_user and put_user */
#include "chardev.h"
#define SUCCESS 0
#define DEVICE_NAME "char_dev"
#define BUF_LEN 80
struct procinfo {
pid_t pid;
pid_t ppid;
struct timespec start_time;
int num_sib;
};
/*
* Is the device open right now? Used to prevent
* concurent access into the same device
*/
static int Device_Open = 0;
/*
* The message the device will give when asked
*/
static char Message[BUF_LEN];
/*
* How far did the process reading the message get?
* Useful if the message is larger than the size of the
* buffer we get to fill in device_read.
*/
static char *Message_Ptr;
/*
* This is called whenever a process attempts to open the device file
*/
static int device_open(struct inode *inode, struct file *file)
{
#ifdef DEBUG
printk(KERN_INFO "device_open(%p)\n", file);
#endif
/*
* We don't want to talk to two processes at the same time
*/
if (Device_Open)
return -EBUSY;
Device_Open++;
/*
* Initialize the message
*/
Message_Ptr = Message;
try_module_get(THIS_MODULE);
return SUCCESS;
}
static int device_release(struct inode *inode, struct file *file)
{
#ifdef DEBUG
printk(KERN_INFO "device_release(%p,%p)\n", inode, file);
#endif
/*
* We're now ready for our next caller
*/
Device_Open--;
module_put(THIS_MODULE);
return SUCCESS;
}
/*
* This function is called whenever a process which has already opened the
* device file attempts to read from it.
*/
static ssize_t device_read(struct file *file, /* see include/linux/fs.h */
char __user * buffer, /* buffer to be
* filled with data */
pid_t pid,
size_t length, /* length of the buffer */
loff_t * offset)
{
/*
* Number of bytes actually written to the buffer
*/
int bytes_read = 0;
#ifdef DEBUG
printk(KERN_INFO "device_read(%p,%p,%d)\n", file, buffer, length);
#endif
/*
* If we're at the end of the message, return 0
* (which signifies end of file)
*/
if (*Message_Ptr == 0)
return 0;
/*
* Actually put the data into the buffer
*/
while (length && *Message_Ptr) {
/*
* Because the buffer is in the user data segment,
* not the kernel data segment, assignment wouldn't
* work. Instead, we have to use put_user which
* copies data from the kernel data segment to the
* user data segment.
*/
put_user(*(Message_Ptr++), buffer++);
length--;
bytes_read++;
}
#ifdef DEBUG
printk(KERN_INFO "Read %d bytes, %d left\n", bytes_read, length);
#endif
/*
* Read functions are supposed to return the number
* of bytes actually inserted into the buffer
*/
return bytes_read;
}
/*
* This function is called when somebody tries to
* write into our device file.
*/
static ssize_t
device_write(struct file *file,
const char __user * buffer, size_t length, loff_t * offset)
{
int i;
#ifdef DEBUG
printk(KERN_INFO "device_write(%p,%s,%d)", file, buffer, length);
#endif
for (i = 0; i < length && i < BUF_LEN; i++)
get_user(Message[i], buffer + i);
Message_Ptr = Message;
/*
* Again, return the number of input characters used
*/
return i;
}
/*
* This function is called whenever a process tries to do an ioctl on our
* device file. We get two extra parameters (additional to the inode and file
* structures, which all device functions get): the number of the ioctl called
* and the parameter given to the ioctl function.
*
* If the ioctl is write or read/write (meaning output is returned to the
* calling process), the ioctl call returns the output of this function.
*
*/
long device_ioctl(struct file *file, /* see include/linux/fs.h */
unsigned int ioctl_num, /* number and param for ioctl */
unsigned long ioctl_param)
{
int i;
char *temp;
char ch;
/*
* Switch according to the ioctl called
*/
switch (ioctl_num) {
case IOCTL_SET_MSG:
/*
* Receive a pointer to a message (in user space) and set that
* to be the device's message. Get the parameter given to
* ioctl by the process.
*/
temp = (char *)ioctl_param;
/*
* Find the length of the message
*/
get_user(ch, temp);
for (i = 0; ch && i < BUF_LEN; i++, temp++)
get_user(ch, temp);
device_write(file, (char *)ioctl_param, i, 0);
break;
case IOCTL_GET_MSG:
/*
* Give the current message to the calling process -
* the parameter we got is a pointer, fill it.
*/
i = device_read(file, (char *)ioctl_param, 99, 0);
/*
* Put a zero at the end of the buffer, so it will be
* properly terminated
*/
put_user('\0', (char *)ioctl_param + i);
break;
case IOCTL_GET_NTH_BYTE:
/*
* This ioctl is both input (ioctl_param) and
* output (the return value of this function)
*/
return Message[ioctl_param];
break;
}
return SUCCESS;
}
/* Module Declarations */
/*
* This structure will hold the functions to be called
* when a process does something to the device we
* created. Since a pointer to this structure is kept in
* the devices table, it can't be local to
* init_module. NULL is for unimplemented functions.
*/
struct file_operations Fops = {
.read = device_read,
.write = device_write,
.unlocked_ioctl = device_ioctl,
.open = device_open,
.release = device_release, /* a.k.a. close */
};
/*
* Initialize the module - Register the character device
*/
int init_module()
{
int ret_val;
/*
* Register the character device (atleast try)
*/
ret_val = register_chrdev(MAJOR_NUM, DEVICE_NAME, &Fops);
/*
* Negative values signify an error
*/
if (ret_val < 0) {
printk(KERN_ALERT "%s failed with %d\n",
"Sorry, registering the character device ", ret_val);
return ret_val;
}
printk(KERN_INFO "%s The major device number is %d.\n",
"Registeration is a success", MAJOR_NUM);
printk(KERN_INFO "If you want to talk to the device driver,\n");
printk(KERN_INFO "you'll have to create a device file. \n");
printk(KERN_INFO "We suggest you use:\n");
printk(KERN_INFO "mknod %s c %d 0\n", DEVICE_FILE_NAME, MAJOR_NUM);
printk(KERN_INFO "The device file name is important, because\n");
printk(KERN_INFO "the ioctl program assumes that's the\n");
printk(KERN_INFO "file you'll use.\n");
return 0;
}
/*
* Cleanup - unregister the appropriate file from /proc
*/
void cleanup_module()
{
unregister_chrdev(MAJOR_NUM, DEVICE_NAME);
#if 0
int ret;
/*
* Unregister the device
*/
ret = unregister_chrdev(MAJOR_NUM, DEVICE_NAME);
/*
* If there's an error, report it
*/
if (ret < 0)
printk(KERN_ALERT "Error: unregister_chrdev: %d\n", ret);
#endif
}
I want to make the syscall using filp_open!!
purpose is file copy!!
but a problem is that i can't find end of file.
opersting system is redhat9 and kernel version is 2.6.32!!
i want to help to me plz!!!!
#include <linux/kernel.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#define BUF_SIZE 4096
asmlinkage int sys_forensiccopy(char *src, char *dst)
{
struct file *input_fd;
struct file *output_fd;
size_t ret_in, ret_out; /* Number of bytes returned by read() and write() */
char buffer[BUF_SIZE]={0,}; /* Character buffer */
int ret;
int i;
mm_segment_t old_fs;
/* Create input file descriptor */
input_fd = filp_open(src, O_RDONLY, 0);
if (input_fd == -1) {
printk ("[!] Can not open the src file");
return 2;
}
/* Create output file descriptor */
output_fd = filp_open(dst, O_WRONLY|O_CREAT, 0644);
if(output_fd == -1){
printk("[!] Can't crate the dstfile");
return 3;
}
old_fs=get_fs();
set_fs(get_ds());
printk("%d\n", input_fd->f_op->read(input_fd,buffer,BUF_SIZE,&input_fd->f_pos));
set_fs(old_fs);
/* Close file descriptors */
filp_close(input_fd,0);
filp_close(output_fd,0);
return 0;
}
I want to write in file chunkcombined.playlist located at the path /var/streaming/playlists/chunkcombined/chunkcombined.playlist using C.
As the files (small chunks of video) get received through a socket, I want to add them automatically to a playlist.
For that I want to write the following lines in the file chunkcombined.playlist using C:
"/usr/local/movies//chunk0.mp4" 1
"/usr/local/movies//chunk1.mp4" 1
"/usr/local/movies//chunk2.mp4" 1
"/usr/local/movies//chunk3.mp4" 5
"/usr/local/movies//chunk4.mp4" 5
How can I write into a file at particular path in Linux using C?
Use fopen() and fputs() functions.
Full example (with excessive comments):
#include <stdio.h>
int main(void)
{
/* where to write */
const char filepath[] =
"/var/streaming/playlists/chunkcombined/chunkcombined.playlist";
/* what to write */
const char output_lines[] =
"\"/usr/local/movies//chunk0.mp4\" 1\n"
"\"/usr/local/movies//chunk1.mp4\" 1\n"
"\"/usr/local/movies//chunk2.mp4\" 1\n"
"\"/usr/local/movies//chunk3.mp4\" 5\n"
"\"/usr/local/movies//chunk4.mp4\" 5\n";
/* define file handle */
FILE *output;
/* open the file */
output = fopen(filepath, "wb");
if(output == NULL) return -1; /* fopen failed */
/* write the lines */
fputs(output_lines, output);
/* close the file */
fclose(output);
return 0;
}
This version retrieves the text line given as argument to the program and then writes it to desired file:
#include <stdio.h>
int main(int argc, char *argv[])
{
if(argv[1] == NULL) return -1; /* no arguments, bail out */
/* where to write */
const char filepath[] =
"/var/streaming/playlists/chunkcombined/chunkcombined.playlist";
/* define file handle */
FILE *output;
/* open the file */
output = fopen(filepath, "wb"); /* change "wb" to "ab" for append mode */
if(output == NULL) return -1; /* fopen failed */
/* write the lines */
fputs(argv[1], output);
putc('\n', output);
/* close the file */
fclose(output);
return 0;
}
Example:
./write "\"Hello, World!\""
writes: "Hello, World!"
to:
/var/streaming/playlists/chunkcombined/chunkcombined.playlist.