Reputation: 153
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
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
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
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