I need to fill my file with same numbers for example 00000.... I want to use asynchronous aio_write function. But here what I get
^# w▒(▒▒▒▒▒l▒#^#Y▒^#^#^#^#▒▒▒▒u▒l▒#*`▒^# w▒h▒▒▒ ......
Here's my code
int main(int argc, char *argv[] ){
int sk;
int d;
struct aiocb aior;
if(argc == 3){
sk = atoi(argv[2]);
char buffer[MB * MB * sk];
memset(&aior, 0, sizeof( struct aiocb ));
d = da_open(argv[1]);
da_aio_write( d, &aior, buffer, sizeof(buffer) );
da_test_wait( &aior );
da_close( d );
}
return 0;
}
and here's my asynchronous writing function (I think this function is bad)
int da_aio_write(const int d, struct aiocb *aiorp, void *buf, const int count){
int rv = 0;
memset( (void *)aiorp, 0, sizeof( struct aiocb ) );
aiorp->aio_fildes = d;
aiorp->aio_buf = buf;
aiorp->aio_nbytes = count;
aiorp->aio_offset = 0;
rv = aio_write( aiorp );
if( rv == -1) {
perror("Error da_aio_write\n");
exit(1);
return rv;
}
return rv;
}
Also here's I wait for asyncronius function to end
int da_test_wait( struct aiocb *aiorp ){
const struct aiocb *aioptr[1];
int rv;
aioptr[0] = aiorp;
rv = aio_suspend( aioptr, 1, NULL );
if( rv != 0 ){
perror( "aio_suspend failed" );
abort();
}
rv = aio_return( aiorp );
printf( "AIO complete, %d bytes write.\n", rv );
return 1;
}
Also here's my full program
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/time.h>
#include <string.h>
#include <aio.h>
#include <errno.h>
#define MB 1024
int da_open(const char *name);
int da_aio_write(const int d, struct aiocb *aiorp, void *buf, const int count);
int da_test_wait( struct aiocb *aiorp );
int da_close(int fd);
int da_open(const char *name){
int dskr;
int dskr2;
dskr = open( name, O_RDWR );
if( dskr == -1 ){
printf("File created\n");
dskr2 = open( name, O_WRONLY | O_CREAT, 0644);
}else{
printf("End job!\n");
exit(1);
}
printf( "dskr1 = %d\n", dskr2 );
return dskr2;
}
int da_aio_write(const int d, struct aiocb *aiorp, void *buf, const int count){
int rv = 0;
memset( (void *)aiorp, 0, sizeof( struct aiocb ) );
aiorp->aio_fildes = d;
aiorp->aio_buf = buf;
aiorp->aio_nbytes = count;
aiorp->aio_offset = 0;
rv = aio_write( aiorp );
if( rv == -1) {
perror("Error da_aio_write\n");
exit(1);
return rv;
}
return rv;
}
int da_test_wait( struct aiocb *aiorp ){
const struct aiocb *aioptr[1];
int rv;
aioptr[0] = aiorp;
rv = aio_suspend( aioptr, 1, NULL );
if( rv != 0 ){
perror( "aio_suspend failed" );
abort();
}
rv = aio_return( aiorp );
printf( "AIO complete, %d bytes write.\n", rv );
return 1;
}
int da_close(int fd){
int rv;
rv = close( fd );
if( rv != 0 ) perror ( "close() failed" );
else puts( "closed" );
return rv;
}
int main(int argc, char *argv[] ){
int sk;
int d;
struct aiocb aior;
if(argc == 3){
sk = atoi(argv[2]);
char buffer[MB * MB * sk];
memset(&aior, 0, sizeof( struct aiocb ));
d = da_open(argv[1]);
da_aio_write( d, &aior, buffer, sizeof(buffer) );
da_test_wait( &aior );
da_close( d );
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/time.h>
#include <string.h>
#include <aio.h>
int da_open(const char *name);
int da_aio_read(const int d, struct aiocb *aiorp, void *buf, const int count);
int da_open(const char *name){
int dskr;
int dskr2;
dskr = open( name, O_RDWR );
if( dskr == -1 ){
dskr2 = open( name, O_WRONLY | O_CREAT, 0644);
}else{
exit(1);
}
return dskr2;
}
What is going on here? Is this an obfuscated way to make sure you don't write to a file if it already exists? It is obviously incorrect as the file could have appeared before the second open. You can use O_EXCL instead.
The code is additionaly obfuscted by not handling exit earlier.
int da_aio_read(const int d, struct aiocb *aiorp, void *buf, const int count){
int rv = 0;
memset( (void *)aiorp, 0, sizeof( struct aiocb ) );
//memset(buf, 0, sizeof( buf) );
aiorp->aio_fildes = d;
aiorp->aio_buf = buf;
aiorp->aio_nbytes = count;
aiorp->aio_offset = 0;
rv = aio_write( aiorp );
return rv;
}
First off, what the fsck. Why are you calling a writing function something_read?
What's the use of rv?
If you read any docs on aio you will see you have to explicitly wait for event completion.
int main(int argc, char *argv[] ){
int sk;
int d;
struct aiocb aior;
char buffer[100];
memset(buffer, 0, sizeof buffer);
if(argc == 3){
sk = atoi(argv[2]);
d = da_open(argv[1]);
da_aio_read( d, &aior, buffer, sizeof(buffer) );
}
return 0;
}
Related
My file should be filled with 0. I want to do that using aio_write As a result my file should look like 000000000.... but as a result I get that my file is filled with garbage
^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#
s|▒^#^#^#^#^#^#^#^#^#^#^#^#▒r|▒^#^#^#^#▒▒^?▒(▒▒▒▒s|▒▒
y▒^P^#^#^#^X▒▒▒
s|▒^X^#^#^#▒.....
I don't even imagine what's wrong. First of all I'm using asynchronous write so I need to wait when da_aio_write is completed
int da_test_wait( struct aiocb *aiorp ){
const struct aiocb *aioptr[1];
int rv;
aioptr[0] = aiorp;
rv = aio_suspend( aioptr, 1, NULL );
if( rv != 0 ){
perror( "aio_suspend failed" );
abort();
}
rv = aio_return( aiorp );
printf( "AIO complete, %d bytes write.\n", rv );
return 1;
}
Also here is my writing function
int da_aio_write(const int d, struct aiocb *aiorp, void *buf, const int count){
int rv = 0;
memset( (void *)aiorp, 0, sizeof( struct aiocb ) );
aiorp->aio_fildes = d;
aiorp->aio_buf = buf;
aiorp->aio_nbytes = count;
aiorp->aio_offset = 0;
rv = aio_write( aiorp );
if( rv == -1) {
perror("Error da_aio_write\n");
exit(1);
return rv;
}
return rv;
}
and my main
int main(int argc, char *argv[] ){
int sk;
int d;
struct aiocb aior;
if(argc == 3){
sk = atoi(argv[2]);
char buffer[MB * MB * sk];
//memset(&aior, 0, sizeof( struct aiocb ));
d = da_open(argv[1]);
da_aio_write( d, &aior, buffer, sizeof(buffer) );
da_test_wait( &aior );
da_close( d );
}
return 0;
}
Any ideas what I'm doing wrong?
EDIT:
I know that my da_aio write ends after main because ehen I compile I get
File created
dskr1 = 3
AIO complete, 1048576 bytes write.
closed
EDIT My full updated code
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/time.h>
#include <string.h>
#include <aio.h>
#include <errno.h>
#define MB 1024
int da_open(const char *name);
int da_aio_write(const int d, struct aiocb *aiorp, void *buf, const int count);
int da_test_wait( struct aiocb *aiorp );
int da_close(int fd);
int da_open(const char *name){
int dskr;
int dskr2;
dskr = open( name, O_RDWR );
if( dskr == -1 ){
printf("File created\n");
dskr2 = open( name, O_WRONLY | O_CREAT, 0644);
}else{
printf("End job!\n");
exit(1);
}
printf( "dskr1 = %d\n", dskr2 );
return dskr2;
}
int da_aio_write(const int d, struct aiocb *aiorp, void *buf, const int count){
int rv = 0;
memset( (void *)aiorp, 0, sizeof( struct aiocb ) );
aiorp->aio_fildes = d;
aiorp->aio_buf = buf;
aiorp->aio_nbytes = count;
aiorp->aio_offset = 0;
rv = aio_write( aiorp );
if( rv == -1) {
perror("Error da_aio_write\n");
exit(1);
return rv;
}
return rv;
}
int da_test_wait( struct aiocb *aiorp ){
const struct aiocb *aioptr[1];
int rv;
aioptr[0] = aiorp;
rv = aio_suspend( aioptr, 1, NULL );
if( rv != 0 ){
perror( "aio_suspend failed" );
abort();
}
rv = aio_return( aiorp );
printf( "AIO complete, %d bytes write.\n", rv );
return 1;
}
int da_close(int fd){
int rv;
rv = close( fd );
if( rv != 0 ) perror ( "close() failed" );
else puts( "closed" );
return rv;
}
int main(int argc, char *argv[] ){
int sk;
int d;
struct aiocb aior;
if(argc == 3){
sk = atoi(argv[2]);
char buffer[MB * MB * sk];
int size;
size = MB * MB * sk;
memset( buffer, '\0', size);
//memset(&aior, '\0', sizeof( struct aiocb ));
d = da_open(argv[1]);
da_aio_write( d, &aior, buffer, sizeof(buffer) );
da_test_wait( &aior );
da_close( d );
}
return 0;
}
char buffer[MB * MB * sk];
Stack variables are not automatically initialiased. So your buffer contains garbage. memset it to 0 first if that's what you want to write to file.
I have two files and I want to copy one file content to other using memcpy. But I get this error Segmentation Fault (core dumped). My main
int main( int argc, char * argv[] ){
int d1;
int d2;
char *a;
char *b;
d1 = da_open_r(argv[1]); // open file READ ONLY
d2 = da_open_w(argv[2]); // open file to WRITE
a = (char*)da_mmap(d1); // map first file
b = (char*)da_mmap(d2); // map second file
memcpy(b, a, 10); // I think this line is bad
kp_test_munamp(a, 10 ); //
kp_test_munamp(b, 10 );
kp_test_close(d1); // close 1 file
kp_test_close(d2); // close 2 file
return 0;
}
and here are my da_mmap and kp_test_munamp
void *da_mmap(int d){
mmap(NULL, 10, PROT_READ|PROT_WRITE, MAP_SHARED, d, 0);
}
int kp_test_munamp( void *a, int size ){
int rv;
rv = munmap( a, size );
if( rv != 0 ){
puts( "munmap failed" );
abort();
}
return 1;
}
I have been trying to fix this almost two hours, but still I don't know what's wrong.
EDIT my full code
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/time.h>
#include <string.h>
int da_open_r(const char *name);
int da_open_w(const char *name);
void *da_mmap(int d);
int kp_test_munamp( void *a, int size );
int kp_test_close(int fd);
int da_open_r(const char *name){
int dskr;
dskr = open( name, O_RDWR );
if( dskr == -1 ){
perror( name );
exit( 255 );
}
printf( "dskr1 = %d\n", dskr );
return dskr;
}
int da_open_w(const char *name){
int dskr;
dskr = open( name, O_RDWR );
if( dskr == -1 ){
perror( name );
exit( 255 );
}
printf( "dskr2 = %d\n", dskr );
return dskr;
}
void *da_mmap(int d){
void *a = NULL;
a = mmap(NULL, 10, PROT_WRITE, MAP_SHARED, d, 0);
if( a == MAP_FAILED ){
perror( "mmap failed" );
abort();
}
return a;
}
int kp_test_munamp( void *a, int size ){
int rv;
rv = munmap( a, size );
if( rv == -1 ){
puts( "munmap failed" );
abort();
}
return 1;
}
int kp_test_close(int fd){
int rv;
rv = close( fd );
if( rv != 0 ) perror ( "close() failed" );
else puts( "closed" );
return rv;
}
int main( int argc, char * argv[] ){
int d1;
int d2;
char *a;
char *b;
d1 = da_open_r(argv[1]); // read only
d2 = da_open_w(argv[2]); // WRITE
a = (char*)da_mmap(d1);
b = (char*)da_mmap(d2);
memcpy(b, a, 10); // I think this line is bad
kp_test_munamp(a, 10 );
kp_test_munamp(b, 10 );
kp_test_close(d1);
kp_test_close(d2);
return 0;
}
da_mmap() does not return anything! Which leads to the values of a and b being garbage and with this most probably pointing to invalid memory, which in turn makes memcpy() fail when acting on it.
Add return statement
void * da_mmap(int d) {
return mmap(NULL, 10, PROT_READ|PROT_WRITE, MAP_SHARED, d, 0);
}
Also you should test the outcome of the mapping by doing:
{
void * pvtmp = da_mmap(d1); // map first file
if (MAP_FAILED == pvtmp)
{
perror("da_mmap() failed");
exit(1);
}
a = pvtmp;
}
The same for b.
Referring the wrapper around munmap(). Correct error testing here. However by convention success is indicated by returning 0 (failure by returning -1).
I have file1.txt
This is my file
and file2.txt
This is my second file
and I want copy file2.txt content to file1.txt using memcpy
int main( int argc, char * argv[] ){
int d;
int d2;
int p;
FILE *f1;
FILE *f2;
if(argc == 3){
f1 = fopen(argv[1], "r+");
f2 = fopen(argv[2], "r+");
d = da_open(argv[1]);
d2 = da_open2(argv[2]);
p = da_cp(f2, f1, 10);
da_map(d, 10);
da_map(d2, 10);
close(p);
//closef(d2);
}
}
I don't know why but when I run this I get file2.txt with lots of random symbols. Why? what I'm doing wrong?
EDIT:
my full code
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/time.h>
#include <string.h>
int da_open(const char *name);
int da_open2(const char *name);
void *da_map(int d, int size);
int da_cp(void *str1, const void *str2, size_t n);
int da_open(const char *name){
int dskr;
dskr = open( name, O_RDONLY, 0640 );
if( dskr == -1 ){
perror( name );
exit( 255 );
}
printf( "dskr = %d\n", dskr );
return dskr;
}
int da_open2(const char *name){
int dskr;
dskr = open( name, O_RDWR, 0640 );
if( dskr == -1 ){
perror( name );
exit( 255 );
}
printf( "dskr = %d\n", dskr );
return dskr;
}
void *da_map(int d, int size){
void *a = NULL;
a = mmap( NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, d, 0 );
if( a == MAP_FAILED ){
perror( "mmap failed" );
abort();
}
return a;
}
int da_cp(void *str1, const void *str2, size_t n){
memcpy(str1, str2, n);
}
int main( int argc, char * argv[] ){
int d;
int d2;
int p;
FILE *f1;
FILE *f2;
if(argc == 3){
f1 = fopen(argv[1], "r+");
f2 = fopen(argv[2], "r+");
d = da_open(argv[1]);
d2 = da_open2(argv[2]);
p = da_cp(f2, f1, 10);
da_map(d, 10);
da_map(d2, 10);
close(p);
//closef(d2);
}
}
d and d2 are not files, they're just file descriptors (something that stores the information about the file and its input/output states).
If you want to copy from 1 file to another, you have to read the first file first. That's the example of how you can do this:
#include <stdio.h>
#include <stdlib.h>
// Open the first text file
FILE *f = fopen("textfile1.txt", "rb");
fseek(f, 0, SEEK_END);
long fsize = ftell(f);
fseek(f, 0, SEEK_SET);
// Read it into buffer
char *buffer = malloc(fsize + 1);
fread(string, fsize, 1, f);
fclose(f);
buffer[fsize] = 0;
// Now write the string buffer into your second text file
FILE *f2 = fopen ("textfile2", "wb");
fwrite (buffer, sizeof(char), sizeof(buffer), f2);
fclose (f2);
So, as you see, the memcpy can only perform with memory in RAM and it has nothing to do with files in hard drive (unless you read it into your RAM memory)
memcpy doesn't work over a file descriptor, you can store the content of file1 in an array of chars (using fgets or fread) and then copy to file2 (using fputs or fwrite)
Also note that you need to use fclose() instead of close() with fopen()
I want to create a file filled with 0 or other letters. Here's my function
int fill(const int d, struct aiocb *aiorp, void *buf, const int count){
int rv = 0;
memset( (void *)aiorp, 0, sizeof( struct aiocb ) ); // <-here second paramether is 0
aiorp->aio_fildes = d;
aiorp->aio_buf = buf;
aiorp->aio_nbytes = count;
aiorp->aio_offset = 0;
rv = aio_write( aiorp );
return rv;
}
Here's my main
int main(int argc, char * argv[]){
int des;
int rv;
struct aiocb aior;
char buffer[1000];
if(argc == 3){
printf("just %s\n", argv[1]);
des = createFile(argv[1]);
rv = fill(des, &aior, buffer, sizeof(buffer));
}
return 0;
}
So my output should be file filled with zero values, but my fle is filled with garbage
^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#$
y▒^X^#^#^#^#^#^#^#
s|▒^#^#^#^#^#^#^#^#^#^#^#^#▒r|▒^#^#^#^#▒▒^?▒(▒▒▒▒▒{▒▒
y▒^P^#^#^#▒
y▒^A^#^#^#d^Cy▒^#^#^#^#▒
y▒^T
y▒^P▒▒▒^#^#^#^#^#^#^#^
...
Why? What's wrong?
Here's the code :
sukurti - create new file if that file don't exist and
fill - fill created file
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <aio.h>
#define MB 1024
int sukurti(char *name);
int fill(const int d, struct aiocb *aiorp, void *buf, const int count);
int sukurti(char *name){
int dskr;
dskr = open( name, O_RDONLY );
if( dskr == -1 ){
printf("Failas sukurtas, nes jo nebuvo\n");
dskr = open( name, O_WRONLY | O_CREAT, 0644);
}else{
printf("Jau yra toks failas!\n");
exit(1);
}
return dskr;
}
int fill(const int d, struct aiocb *aiorp, void *buf, const int count){
int rv = 0;
memset( (void *)aiorp, 'A', sizeof( struct aiocb ) );
aiorp->aio_fildes = d;
aiorp->aio_buf = buf;
aiorp->aio_nbytes = count;
aiorp->aio_offset = 0;
rv = aio_write( aiorp );
return rv;
}
int main(int argc, char * argv[]){
int des;
int rv;
struct aiocb aior;
int x = atoi(argv[2]);
printf("%d\n", x);
int size = MB * MB * x;
char buffer[size];
if(argc == 3){
printf("just %s\n", argv[1]);
des = sukurti(argv[1]);
rv = fill(des, &aior, buffer, sizeof(buffer));
}else{
printf("Blogas\n");
}
return 0;
}
EDIT:
I know that my writting to file ends
Three ssues here:
buffer is not initalised. Do this using
memset(buffer,
<what ever 8bit value you want the file to be filled with>,
sizeof buffer);
right after defining it in main().
aior is initialise wrongly. Initialise it to all 0 using
memset(aiorb, 0, sizeof aior);
right after defining it in main() and remove the call to memset() in fill().
Finally the program most likely ends before the buffer had been asynchronously written to disk.
To fix this define a notification method as mentioned under man 7 aio. And make the program wait for this notification to be received before ending the program.
This for example can be done by asking for completion notification via signal and wait for this signal.
To do so modify your code as follows:
Add the following two lines to the intialisation of what aiorp is pointing to in fill():
aiorp->aio_sigevent.sigev_notify = SIGEV_SIGNAL;
aiorp->aio_sigevent.sigev_signo = SIGUSR1;
To be able to handle the notifying signal sent (without ending the program) a signal handler needs to be setup:
void handler(int sig)
{
/* Do nothing. */
}
Install this handler by calling
signal(handler, SIGUSR1);
right at the beginning of the program.
Before returning from main() call wait_for_completion(SIGUSR1) which might look like this:
void wait_for_completion(int sig)
{
sigset_t set;
sigemptyset(&set);
sigaddset(&set, sig);
sigwait(&set, &sig); /* This blocks until sig had
been received by the program. */
printf("Completion notification for asynchronous 'write'-operation received.\n");
}
Add error handling as appropriate. I left it out for the sake of readability.
memset( (void *)aiorp, '0', sizeof( struct aiocb ) );
0 is not '0', you need to actually use the ASCII value (48 if i recall correctly.)
i m trying to modify fuse example to mount any directory. I want to mount /home/nikhil in tmp.
i ran it as,
$ ./ni /home/nikhil tmp
It mounts tmp folder, but cannot access it.
$ls -ltr tmp
ls: cannot access tmp: Operation not permitted
$ ls -ltr
ls: cannot access delete: Operation not permitted
total 11716
d????????? ? ? ? ? ? delete
My code is
#define FUSE_USE_VERSION 26
#include <fuse.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <limits.h>
#include <unistd.h>
#define MAX 100
char *rootpath;
static void ni_fullpath(char fpath[MAX], const char *path){
strcpy(fpath, rootpath);
strncat(fpath, path, MAX);
}
static int ni_getattr(const char *path, struct stat *stbuf)
{
int res = 0;
char fpath[MAX];
memset(stbuf, 0, sizeof(struct stat));
ni_fullpath(fpath, path);
res = lstat(fpath, stbuf);
return res;
}
static int ni_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
off_t offset, struct fuse_file_info *fi)
{
(void) offset;
(void) fi;
// i didnt understand this
filler(buf, ".", NULL, 0);
filler(buf, "..", NULL, 0);
ni_fullpath(fpath, path);
filler(buf, fpath + 1, NULL, 0);
return 0;
}
static int ni_open(const char *path, struct fuse_file_info *fi)
{
int fd;
char fpath[MAX];
ni_fullpath(fpath, path);
if ((fi->flags & 3) != O_RDONLY)
return -EACCES;
fd = open(fpath, fi->flags);
return fd;
}
static int ni_read(const char *path, char *buf, size_t size, off_t offset,
struct fuse_file_info *fi)
{
return pread(fi->fh, buf, size, offset);
}
static struct fuse_operations ni_oper = {
.getattr = ni_getattr,
.readdir = ni_readdir,
.open = ni_open,
.read = ni_read,
};
void ni_usage(){
fprintf(stderr, "usage ni rootDir mountPoint");
abort();
}
int main(int argc, char *argv[])
{
printf("%s %s \n", argv[1], argv[2]);
rootpath = realpath(argv[1], NULL);
argv[1] = argv[2];
argc--;
return fuse_main(argc, argv, &ni_oper, NULL);
}
Can anybody help what i m doing wrong ?
I m using ubuntu 1104 64 bit.
How about using uninitialized var fpath instead of path?
static int ni_getattr(const char *path, struct stat *stbuf)
{
int res = 0;
char fpath[MAX];
memset(stbuf, 0, sizeof(struct stat));
res = lstat(fpath, stbuf);
return res;
}
You probably missed ni_fullpath(fpath, path);
And as far as I understand the 0 should be returned in open callback if success, so it should look like:
....
fd = open(fpath, fi->flags);
if (fd < 0)
return -errno;
fi->fh = fd;
return 0;
}
List operation should uses readdir callback, and in your case it has very limited application. It'd be better to start code on the basis of fusexmp. Check how readdir is implemented there.