Getting file too large error while using catopen() function - c

I'm getting errno 27[EFBIG]: file too large while opening catalogue with catopen() function in cygwin-32bit version. How to resolve it?
Note: File size is 44kb.
Trying to open .cat file but catopen() returns file too large [EFBIG] error.
this is the code snippet I was working with:
#define FILENAME TEMP.CAT
buffer = catopen(FILENAME, 0);
if (buffer != (nl_catd) - 1)
{
printf("File open successfully");
}
else
{
printf("errno: %d\n", errno);
}
while debugging I've found that st.st_size is 0 and I'm not sure about the value of SIZE_T_MAX parameter i think it may be have garbage value .so that's why if condition getting success and returning errno 27(EFBIG).
Coding snippet where if condition getting succeed:
if (st.st_size > SIZE_T_MAX) {
_close(fd);
SAVEFAIL(name, lang, EFBIG);
NLRETERR(EFBIG);
}

Related

Will errno == ENOENT be a sufficient check to check if file exists in C?

Using PellesC on Windows 8.1.
I know this topic has been addressed many times with many solutions. I have read solutions stating the usage of CreateFile, PathFileExists, GetFileAttributes, _access which I somewhat understand.
I have also read an important point about race conditions in the answer to the questions Quickest way to check whether or not file exists
and What's the best way to check if a file exists in C? (cross platform).
So if I open a file using fopen() in C and when it fails (for any reason) and passes NULL back; then can I further check for errno == ENOENT and be content with it and report correctly that the file does not exists.
#include <stdio.h>
#include <string.h>
#include <errno.h>
int file_exists(char filename[]) {
int err = 0; //copy of errno at specific instance
int r = 0; //1 for exists and 0 for not exists
FILE *f = NULL;
//validate
if (filename == NULL) {
puts("Error: bad filename.");
return 0;
}
printf("Checking if file %s exists...\n", filename);
//check
errno = 0;
f = fopen(filename, "r");
err = errno;
if (f == NULL) {
switch (errno) {
case ENOENT:
r = 0;
break;
default:
r = 1;
}
printf("errno = %d\n%s\n", err, strerror(err));
} else {
fclose(f);
r = 1;
}
if (r == 0) {
puts("It does not.");
} else {
puts("It does.");
}
return r;
}
fopen needs to do lots of stuff and checking before the file is opened. ENOENT implies that the file does not exist, but file not existing does not imply ENOENT.
It is possible for a file to not exist and you to get another error, such as EACCES for not being able to read the parent directory for example.
On the other hand, ENOENT from fopen does not mean that some other process couldn't have created the file even before fopen returns or before you're inspecting the errno and so on; this is the reason why C11 added the x flag for opening a file for writing in exclusive mode - failing if the file already exists.
To sum it up: if you get ENOENT, the file did not exist when you tried opening it. If you get some other error, then each other error code would belong to one of 3 these classes - that it is certain that either
the file existed, or
it cannot have existed
or it might have existed at the time
at the time of opening. It is up to you and your required logic how you'd handle these other errors. A simple way would be to refuse to continue processing, reporting the error to the user.

open() file does not exists when file actually exists

I'm writing a simple HTTP server and I'm getting a file does not exists return value when the file does exist
printf("%s\n", html_path);
if ((fd = open(html_path, "r")) >= 0){ //file found
stat(file_name, &st);
file_size = st.st_size;
printf("%d\n", file_size);
while (read(fd, response, RCVBUFSIZE) > 0){
}
}
else { //file not found
strcpy(response, "404 File not found\n");
send(clntSocket, response, 32, 0);
}
the print statement is to verify the path and it looks like this:
/mounts/u-zon-d2/ugrad/kmwe236/HTML/index.html
note that this path is on a server that we use at our university. it's the path that shows when I command pwd
I have confirmed that the file exists. is there something wrong with my path?
There was an error opening the file, but you don't know that it was because the file was not found because you're didn't check the value of errno.
In the else section, add the following:
else { //file not found
// copy the value of errno since other function calls may change its value
int err = errno;
if (err == ENOENT) {
strcpy(response, "404 File not found\n");
send(clntSocket, response, 32, 0);
} else {
printf("file open failed: error code %d: %s\n", err, strerror(err));
}
}
If the file does not in fact exist you'll handle the error properly. If not, you'll print an error message that tells you what did happen.
You're also calling open incorrectly. The second parameter is an int containing flags. To open a file for reading, use O_RDONLY.
open does not have the 2nd parameter as a string. You using open with the parameters of fopen.
For a webserver fopen, fprintf, fclose is a better choise then more lowlevel open, read, ...
Cheers,
Chris
You need to check where you program is executing as it will try to open the path relative from that location. To check use:
char cwd[1024];
getcwd(cwd, sizeof(cwd));
puts(cwd);
Then you can concatenate your path using:
strncat(cwd, html_path, 100);
You may find that you have to go up one directory or something to then find the file you're looking for.
Also note that if you're debugging your program via gdb it may execute from a different location from your regular build location which may make it harder to spot bugs.

Obtaining permissions for a file in C

I am looking for a way to check and make sure a file is readable, writeable, and exists, and if it is not I want to print a message stating so. I believe the information I am looking for can be found using fstat(), I just don't know the correct way to get it.
If open sets a specific errno if I try to open a unreadable, unwriteable, or non-existant file with O_RDRW, I think that would be the ideal solution.
Here is what I have tried:
//function to open the file
int f_open(const char *filename){
int fid;
if ((fid = open (filename, O_RDWR)) < -1){
return -1;
}
struct stat fileStat;
if (fstat(fid, &fileStat) < 0){
return -1;
}
//check write permission
if (!S_IWUSR(fileStat.st_mode)){
printf("Not writeable\n");
return -1;
}
//check read permissions
if (!S_IRUSR(fileStat.st_mode)){
printf("Not readable\n");
return -1;
}
return fid;
}
I am receiving the following error when I try and compile:
tester.c: In function 'f_open':
tester.c:56:14: error: called object '128' is not a function
tester.c:60:14: error: called object '256' is not a function
The macros you are using are bit values, not functions.
//check write permission
if ((S_IWUSR & fileStat.st_mode) == 0){
printf("Not writeable\n");
return -1;
}
Example Here: http://codewiki.wikidot.com/c:system-calls:fstat
EDIT: The 'access' function indicated above is a better choice IWUSR doesnt tell you if YOU can write it, it tells you if the owner can.
You can use access for permission checking
int rw = access(filename, R_OK | W_OK);
if (rw == 0) {
/* read/write granted */
}

c read() causing bad file descriptor error

Context for this is that the program is basically reading through a filestream, 4K chunks at a time, looking for a certain pattern. It starts by reading in 4k, and if doesn't find the pattern there, it starts a loop which reads in the next 4k chunk (rinse and repeat until EOF or pattern is found).
On many files the code is working properly, but some files are getting errors.
The code below is obviously highly redacted, which I know might be annoying, but it includes ALL lines that reference the file descriptor or the file itself. I know you don't want to take my word for it, since I'm the one with the problem...
Having done a LITTLE homework before crying for help, I've found:
The file descriptor happens to always = 6 (it's also 6 for the files that are working), and that number isn't getting changed through the life of execution. Don't know if that's useful info or not.
By inserting print statements after every operation that accesses the file descriptor, I've also found that successful files go through the following cycle "open-read-close-close" (i.e. the pattern was found in the first 4K)
Unsuccessful files go "open-read-read ERROR (Bad File Descriptor)-close." So no premature close, and it's getting in the first read successfully, but the second read causes the Bad File Descriptor error.
.
int function(char *file)
{
int len, fd, go = 0;
char buf[4096];
if((fd = open(file, O_RDONLY)) <= 0)
{
my_error("Error opening file %s: %s", file, strerror(errno));
return NULL;
}
//first read
if((len = read(fd, buf, 4096)) <= 0)
{
my_error("Error reading from file %s: %s", file, strerror(errno));
close(fd); return NULL;
}
//pattern-searching
if(/*conditions*/)
{
/* we found it, no need to keep looking*/
close(fd);
}
else
{
//reading loop
while(!go)
{
if(/*conditions*/)
{
my_error("cannot locate pattern in file %s", file);
close(fd); return NULL;
}
//next read
if((len = read(fd, buf, 4096)) <= 0) /**** FAILS HERE *****/
{
my_error("Error reading from file, possible bad message %s: %s",
file, strerror(errno));
close(fd); return NULL;
}
if(/*conditions*/)
{
close(fd);
break;
}
//pattern searching
if(/*conditions*/)
{
/* found the pattern */
go++; //break us out of the while loop
//stuff
close(fd);
}
else
{
//stuff, and we will loop again for the next chunk
}
} /*end while loop*/
}/*end else statement*/
close(fd);
}
.
Try not to worry about the pattern-reading logic - all operations are done on the char buffer, not on the file, so it ought to have no impact on this problem.
EOF returns 0 (falls into if ... <= 0), but does not set errno, which may have an out of date code in it.
Try testing for 0 and negative (error, -1) values seperately.
Regarding "strace": I've used it a little at home, and in previous jobs. Unfortunately, it's not installed in my current work environment. It is a useful tool, when it's available. Here, I took the "let's read the fine manual" (man read) approach with the questioner :-)

Segmentation fault while using ferror() in a simple program. Why?

Why is the following code giving segmentation fault?
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *file;
file = fopen("text","r");
if (file == NULL) printf("Error READING FILE");
if (ferror(file)) printf("error reading file"); //line 9
return 0;
}
Doing backtrace in gdb gives:-
> #0 0x00007ffff7ad9d30 in ferror () from /lib/libc.so.6
> #1 0x00000000004005fa in main () at test.c:9
file is NULL. You're not seeing the first printf because the program crashes before stdout is flushed.
If fopen returns NULL, then the file isn't open; you're passing NULL in to ferror, which is invalid. You don't have an open file to pass in; that's what NULL means, that it couldn't give you a file pointer. ferror is for getting errors related to reading and writing the file, once it has actually been opened and you have the file to work with.
If fopen fails, and you want to get more information about why, you need to check the errno global variable, defined in errno.h.
#include <errno.h>
// ...snip...
if (file == NULL)
printf("Error READING FILE: %s\n", strerror(errno));
This example shows how to fetch a string describing the error; you could also compare the value in errno against one of the possible values it could have, and do something different depending on what the error is. See the fopen man page, or the POSIX spec, for a list of possible errors to compare against. Here's how you could check against various possible errors:
if (file == NULL) {
int error = errno; // copy it so other calls like printf don't modify it
printf("Error READING FILE: %s\n", strerror(error));
switch (error) {
case EACCESS:
// access was denied
break;
case ENOENT:
// the file or one of its ancestors doesn't exist
break;
// etc...
}
}
(this is an expansion of something I originally wrote in a comment on another answer)
If file is equal to NULL on line 9, then the Seg Fault will occur during the ferror() call.
If there the file is NULL (as determined on line 8), then you shouldn't perform line 9.
Your line 8 code should be changed as such:
if (file == NULL)
{
printf("Error READING FILE");
return 1;
}
NB: i could be very wrong about this, it's been a while since i've done C/C++

Resources