1

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

David
  • 3,055
  • 4
  • 30
  • 73
  • 2
    Maybe, you shall clear the `buffer` before writing it. – Marian Apr 28 '15 at 14:24
  • 1
    what/where is your _output_ function? – Sourav Ghosh Apr 28 '15 at 14:25
  • `^@` *is* `0`, so no worries where we see that. You're setting `aio_fildes` to an uninitialized integer value, so that'll show up as garbage in the file. Not sure what your output function looks like, but you're pointing `aio_buf` to an uninitialized `buffer`, so that should also be full of garbage (or, if you're just printing the pointer value, it still won't be `0`). `aio_nbytes` certainly won't be `0`, either. Please show the output function; as it is, nothing here is surprising. – Paul Roub Apr 28 '15 at 14:30
  • 1
    Just as a simple note, put your code here and don't let it on other sites, so if in a year someone watches this link he can get full data available – Mekap Apr 28 '15 at 14:39
  • What is the value you type in for `x`/`argv[2]`? How do you call this program? Can you post the exact command line? I strongly suspect your command line is misformed somehow, then atoi can't convert the value to something that makes sense. You really need to add more sanity checks of the command line arguments and defensive programming. – Lundin Apr 28 '15 at 14:53
  • Is there any particular reason you (try to) use `aio_write()` and not just simply `write()`? – alk Apr 28 '15 at 15:47
  • Well, yes I need to use aio_write() – David Apr 28 '15 at 15:49
  • 1
    Besides you are not initialising the buffer to be written, `main()` propably ends before the asynchronous write completed. To avoid this make sure to setup a notification on when the write completed and do not leave `main()` until this notification was received. See the member `aio_sigevent` of `struct aiocb` for this. Also see `man aio` and `man sigevent` for details. – alk Apr 28 '15 at 15:54
  • @SouravGhosh: It's the call to `aio_write()`. – alk Apr 28 '15 at 17:07

2 Answers2

5

Three ssues here:

  1. 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().

  2. 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().

  3. 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.

alk
  • 69,737
  • 10
  • 105
  • 255
4
  memset( (void *)aiorp, '0', sizeof( struct aiocb ) );

0 is not '0', you need to actually use the ASCII value (48 if i recall correctly.)

Mekap
  • 2,065
  • 14
  • 26
  • Well, isnt that what you want ? A file filled with the caracter 0 ? @David – Mekap Apr 28 '15 at 14:27
  • Well, if I want to have a file filled with 'A' characters? – David Apr 28 '15 at 14:28
  • then you just write memset( (void *)aiorp, 'A', sizeof( struct aiocb ) ); and it works ! – Mekap Apr 28 '15 at 14:28
  • 2
    from man aio: `The aiocb ("asynchronous I/O control block") structure defines parameters that control an I/O operation.` So, don't fill it with garbage. What must be filled is the buffer. – Diego Apr 28 '15 at 14:31
  • I posted my full code. When I write memset( (void *)aiorp, 'A', sizeof( struct aiocb ) ); I still get file with 0 size. – David Apr 28 '15 at 14:33
  • @David OK, i think i know what's wrong ! Can you change your memset to memset( buf, 'A', sizeof( buf) ); ? And then tell me if that was ok. If it worked i'll edit my answer and tell you why you got that error. – Mekap Apr 28 '15 at 14:37
  • sorry. still file with 0 size. – David Apr 28 '15 at 14:42
  • @David Are you sure ? I don't see why you're not getting something different – Mekap Apr 28 '15 at 14:54
  • Well I changed to memset( buf, 'A', sizeof( buf) ); in my fill method, but I get same results :/ – David Apr 28 '15 at 14:57
  • @David just a quick thing, are you forced to use aio_write ? And where is your close ? Are you sure to check the same file ? – Mekap Apr 28 '15 at 15:07
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/76464/discussion-between-david-and-mekap). – David Apr 28 '15 at 15:11
  • This is not the only cause, why the output file stays empty. – alk Apr 28 '15 at 16:54