I have a part of C program:
char buf[256];
fprintf(stderr, "buf created. going to freopen. Path:\n");
fprintf(stderr, path);
fprintf(stderr, "\n");
if (!freopen(path, "a", stderr)) {
fprintf(stderr, "if entered\n");
fprintf(stderr, "Can't redirect stderr\n");
sprintf(buf, "Server can't open log file (%s)", path);
fprintf(stderr, "sprintf ok. going to send_message\n");
send_message(buf, config.maintenance_delay);
fprintf(stderr, "send_message ok\n");
exit(1);
}
fprintf(stderr, "ndef USING_FCGI, ended\n");
And the output for it is:
buf created. going to freopen. Path:
../log_andrewwhynot/scheduler.log
Segmentation fault
So, I assume the problem is in the freopen() function but I'm unable to figure out what is wrong with it. I've double-checked the path to the file (it exists and everything is ok with access rights) and even tried to hardcode the absolute path or use path to another file, but everything was in vain. Then, I tried to open the file for write action instead of append, but it did not help as well. So, what might be wrong? Why does the call cause SIGSEGV?
Thank you!
Architecture: arm64
OS: armbian nightly 5.41.180312
gcc version: (Ubuntu GLIBC 2.23-0ubuntu10) 2.23
Related
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.
I wrote a program using c, which I use popen to open a pipe and execute a command line.
This program works fine in host, but when I run the program in vbox, ubuntu12.04, error:can not allocate memory displayed.
My code is:
FILE *fp;
char path[100];
/* Open the command for reading. */
fp = popen(pdpcall, "r");
if (fp == NULL) {
printf("Error opening pipe pdpcall: %s\n",strerror(errno));
pclose(fp);
exit(0);
}
/* Read the output a line at a time - output it. */
while (fgets(path, sizeof(path)-1, fp) != NULL) {
if(strncmp(decision,path,strlen(decision))==0)
{
pclose(fp);
return 1;
}
I also try a test program only have popen in VM, it works fine. But can not work within my program.
I guess the reason is that in my program, I use a lot of malloc, and might not free. The memory in Vbox is smaller than host, so there are memories errors.
But I change the vbox memory from 512m to 2G, it still the same errors.
Is there any other problems within VM. How to solve this problems.
I'm trying to write data to a file and it's not appearing but I know the program is finishing. I establish a writable file getting the name from a command argument
FILE *outFilePtr;
Then I create the file through:
outFilePtr=fopen(outFileString,"w"); //outFileString is the name of the file from command
Now I attempt to print to this file which has a .mc extension:
fprintf(outFilePtr,"%s\n","1001") //example string
The file gets created and nothing is written to it. This is probably a dumb question but can you not write strings to machine code files? I'm trying to find a solution to this problem if that's the case.
You should check the results of fopen and fprintf. This works for me:
#include <stdio.h>
#include <errno.h>
int
main(int argc, char *argv[])
{
FILE *outFilePtr;
outFilePtr = fopen("asdf.mc", "w");
if(!outFilePtr) {
perror("Couldn't open it");
fprintf(stderr, "errno: %d\n", errno);
exit(-1);
}
if(fprintf(outFilePtr, "%s\n", "1001") < 0)
{
fclose(outFilePtr);
perror("Couldn't write to it");
fprintf(stderr, "errno: %d\n", errno);
exit(-1);
}
fclose(outFilePtr);
}
If there is a problem opening the file (permissions, etc), perror will show it. For example, using an empty string for the filename gave me this in a window$ machine:
Couldn't open it: Invalid argument
errno: 22
If I close outFilePtr before the fprintf, this error gets displayed:
Couldn't write to it: Bad file descriptor
errno: 9
please check that you close the file(using fclose(fptr)) after fprintf()..
When an error occurs, I would like my C code to store the error before exiting the program. Is it advised to store the stderr to a file (e.g., /home/logs.txt) or would it be advised to use a different method to keep the logs/error report (considering the programming environment is Linux). E.g., for the code below, how I could apply the method to store the logs/error message on /home/log.txt or /home/log
FILE *fp1;
fp1 = fopen("/sys/class/gpio/export","w");
if(fp1 == NULL){
fprintf(stderr, "errno:%s - opening GPIO136 failed - line 739\n ", strerror(errno));
close(fp1);
exit(1);
}
Thank you.
If stderr is always used to print out all your error message, so, you can redirect output to a specific file.
$ program 2>~/logs.txt
For a better logging tool, you can use:
syslog standard function.
log4c library.
If you want to store the error, stderr is probably not a good choice because you'll need to pipe stderr to a file every time you run the program.
If you want to write to /home/log.txt, open a FILE pointer to it and write with fprintf the same way you tried to open /sys/class/gpio/export and write to that instead of stderr. Also be sure to open the log file with append mode.
FILE *fp1;
fp1 = fopen("/sys/class/gpio/export","w");
if(fp1 == NULL){
FILE *fpErr = fopen("/home/log.txt", "a");
if(fpErr != NULL)
fprintf(fpErr, "errno:%s - opening GPIO136 failed - line 739\n ", strerror(errno));
close(fpErr);
close(fp1);
exit(1);
}
I have written a code in c, for file handling. The file name has some German characters in it. This code is working perfectly on Windows. But it is not working in Linux. fopen is giving 'Could not open file' error.
I have checked the file path, the file exists there. Also, I have read write permission for that folder.
The code is as below.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
const char *fileName = "/users/common/haëlMünchen.txt";
FILE * pFile;
char errorMessage[256];
pFile = fopen (fileName,"r");
if (pFile != NULL)
{
fprintf (stdout,"fopen example",errorMessage);
fclose (pFile);
}
else
{
sprintf(errorMessage, "Could not open file %s", fileName);
fprintf(stdout, "%s\n", errorMessage);
}
return 1;
}
Any inputs on this?
On Linux you could replace your sprintf call with
snprintf (errorMessage, sizeof(errorMessage),
"Could not open file %s - %m", fileName);
(A general hint is to avoid sprintf because of possible buffer overflows and only use snprintf)
If you want to avoid the GLibc specific %m format specifier, and use more standard functions, code
snprintf (errorMessage, sizeof(errorMessage),
"Could not open file %s - %s",
fileName, strerror(errno));
and don't forget the #include <errno.h>, and read carefully the errno(3) man page.
BTW, you could avoid doing both snprintf and printf and simply code
fprintf (stderr, "Cannot open file %s - %s\n",
fileName, strerror(errno));
(error reporting usually go to stderr, as Jonathan reminded)
Then run your program again. Perhaps you have an issue with character encoding (either in the source file, or in the filesystem).
You could also use strace (and perhaps ltrace) on your program to understand the actual syscalls it is doing.