ligazetom
ligazetom

Reputation: 153

How to print errno while saving the value from function?

I am not able to open/create a file properly using open() function, so I thought that using errno messages will help me to figure out the reason. However I don't know how to set the if(), so it prints me the error. I know the code like this should work:

if(open(handle,O_RDWR | O_CREAT) == -1){
      printf("%s\n",strerror(errno));
}

but what if I want to save the value from open() to my variable and IF it is -1 then print the error as well? I don't want to call open() twice for this and I don't know how to assign it if it is ok and how to print error if not.

 #include <stdio.h>
    #include <stdlib.h>
    #include <fcntl.h>
    #include <ctype.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <string.h>
    #include <errno.h>


    int main(int argc, char **argv){
        int handle,i,help;
        int *array = malloc(5*sizeof(int));
        float *red = malloc(5*sizeof(int));

        array[0]=5;
        array[1]=4;
        array[2]=3;
        array[3]=2;
        array[4]=1;

        handle = open(argv[1], O_RDWR | O_CREAT);
        if(handle == -1){
            printf("%s\n",strerror(errno));
        }

        printf("handle 1 %d\n",handle);
        write(handle,array,20);
        close(handle);

        handle = open(argv[1], O_RDONLY);
        lseek(handle,0,SEEK_SET);
        printf("handle %d\n",handle);
        help=read(handle,&red,20);
        printf("pomoc %d\n",help);
        for(i=0; i<5; i++){
            printf("%d\n",(int)red[i]);
        }
        close(handle);
        return 0;
    }

Upvotes: 4

Views: 8547

Answers (3)

Paul Ogilvie
Paul Ogilvie

Reputation: 25266

The proper way to do this is:

    if((handle=open(argv[1], O_RDWR|O_CREAT, 0666)) == -1){

Note that the pmode argument is required for O_CREAT.

Upvotes: 1

zwol
zwol

Reputation: 140445

The problem is not with assigning to a variable, it's the way you're calling open:

handle = open(argv[1], O_RDWR|O_CREAT); // wrong number of arguments
if (handle == -1) {
    printf("%s\n",strerror(errno));
}

When you use O_CREAT, you must give open three arguments. If you don't, the behavior is undefined. By accident, you were getting a −1 error return when you had the open call inside the if, and a nonnegative return value when you assigned it to a variable.

Unless you have a concrete reason to do otherwise, the third argument to open should be the magic number 0666. (The most common concrete reason to do otherwise is that you are creating a file which will hold secret information; then you use 0600.) (The leading zero is required.) There are symbolic constants that can be used for the third argument to open but, once you know what numeric "modes" mean, the symbolic constants are actually harder to read. Here is a detailed explanation of "modes" in both symbolic and numeric forms.

Incidentally, when a system call fails you should always print both strerror(errno) and the name of the offending file (if any):

handle = open(argv[1], O_RDWR|O_CREAT, 0666);
if (handle == -1) {
    printf("%s: %s\n", argv[1], strerror(errno));
    exit(1);
}

And you should think about whether you should be using O_EXCL or O_TRUNC.

Upvotes: 3

unwind
unwind

Reputation: 399713

It looks like you're doing it just right; just save the return value of open() to a variable, then compare that against -1. Fine.

Note that this is broken:

float *red = malloc(5*sizeof(int));

since there's no guarantee that a float is the same size as an int, this is wrong and very confusing. It's better to not repeat the type in the malloc() since that risks introducing this error. Instead, do:

float * const red = malloc(5 * sizeof *red);

This uses sizeof *red to compute sizeof (float), while making sure the type is that of an actual pointer in your program. Also note use of const to protect against red being re-assigned later, which might create a memory leak.

Upvotes: 0

Related Questions