For the following snippet of code, I get an error:
Unable to open file: No such file or directory
redirect_ptr is char**
And I have tried printing redirect_ptr[0], it prints it correctly. Any idea where the problem might lie?
if ((in_fd = open(redirect_ptr[0], O_RDWR | O_CREAT)) == -1) {
perror("Unable to open file");
return -1;
}
When you create a file, open() needs an additional argument, the permission bits on the file to create.
You need to do e.g.
if ((in_fd = open(redirect_ptr[0], O_RDWR | O_CREAT, 0644) == -1)
That might not be the cause of the error you get, however if the error is "No such file or directory", then that's precisely what is wrong, you program cannot find the file.
Perhaps you have some non-printable characters in the file name, or the name ends with a space or newline or similar, or you spelled the name wrong, or have the wrong case, or the path is a relative path that doesn't match the file based on the current working directory of your process.
It's often helpful to print the filename inside a pair of '' , so you can see if there's some whitespace that should not be there. add a
printf("Filename: '%s'\n",redirect_ptr[0]);
to your code. And if it looks good, do a ls -l on the filename it prints out, standing in the working directory of the process.
Related
So I am using the open function in C to open a target file, and if it does not exist, I will create it. I am redirecting stdout from the terminal into this file. When I run my program, it creates a new file with the name that I type into the shell, but appends a "?" to the end. Can someone help me figure out how to remove that?
My code is below
// Take output from ls as input into the next argument.
command = strtok(NULL, " "); // Holds the value for the destination file.
printf("%s\n", command);
int targetFD = open(command, O_WRONLY | O_CREAT | O_TRUNC, 0700);
if (targetFD == -1)
{
perror("open()");
exit(1);
}
printf("The file descriptor for targetFD is %d\n", targetFD);
int result = dup2(targetFD, 1);
if (result == -1)
{
perror("dup2");
exit(2);
}
ls(); // instead of printing ls to the terminal, it gets written to the file.
Here is an image of a sample execution. Notice how junk.txt file already exists...I want my program to redirect "ls" into that file or create a new one of the file does not exist.
sample program execution
I bet the ? is not a literal ? character, but the way that your version of ls displays a filename containing a non-printable character, e.g. if you use GNU ls and have the -q option enabled by default.
I also note that in your sample output, there is an extra blank line between junk.txt and The file descriptor for targetFD. You only printed one newline after command, so I suspect that the string command itself ends with a \n. That would fit if it was parsed from a string that ended with \n (e.g. a line read with fgets). So you actually created a file named junk.txt\n, and ls prints the newline character as ?.
Perhaps you wanted to use " \n" as the delimiter string for strtok, so that a newline will also be treated as a delimiter and not be included in the token string.
I am compiling an Angband variant on Raspbian, and the following fails:
struct stat txt_stat, raw_stat;
/* Build the filename */
path_build(buf, 1024, ANGBAND_DIR_EDIT, template_file);
/* Access stats on text file */
if (stat(buf, &txt_stat))
{
/* Error */
msg_format("Oh dear, something went wrong with stat()! %s", strerror(errno));
msg_format("Could not retrieve stats on the text file at {%s}", buf);
return (-1);
}
What annoys me to no end is that the file is there at
~/git/hellband/lib/edit/r_info.txt
When I replace the above code with code that opens the file (using the same buf) and then use fstat() on the file descriptor, it works!!
I dont want to open a file (and remember to close that file), I just want to know/fix what is going on with stat().
PostScriptum 2020; it turned that when I used the Angband approach to opening files, it autoexpanded the ~ sign, which is why that worked, and fstat worked.
It's simple. stat(2) doesn't expand or understand ~ (tilde).
You could HOME instead. For example, getenv("HOME") and then prefix it with your filename before calling stat(2).
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.
Language: C
OS: Ubuntu
I'm simply trying to create a FIFO named pipe using the command:
state = mknod("pipe.txt", S_IFIFO | 0666, 0);
the problem is i always get the state's value to be -1 (meaning it has failed) instead of 0.
perror returns 'pipe.txt: File exists'
i have no idea how should i debug such issue or what could be the reason, hope anyone code guide me what's wrong.
(note: the file pipe.txt exist on same path as source file.)
Read: int mknod(const char *path, mode_t mode, rdev_t dev_identifier);
General Description:
Creates a new character special file or FIFO special file (named pipe), with the path name specified in the path argument.
If file already exists then it will fails with error: File exists
To avoid this error, remove(unlink()) the file, As I am doing in my below code(read comment):
int main() {
char* file="pipe.txt";
unlink(file); // Add before mknod()
int state = mknod(file, S_IFIFO | 0666, 0);
if(state < 0){
perror("mknod() error");
}
return 0;
}
You should examine errno to see what the error is but it's probably EEXIST since I believe that's what happens if the file already exists.
From the Linux documentation for mknod:
If pathname already exists, or is a symbolic link, this call fails with an EEXIST error.
However, if the file already exists and is the pipe you created in an earlier run, you can safely reopen it. All mknod (and its often preferred cousin, mkfifo) does is actually create the FIFO, you still have to open it at both ends to get the data transfer happening.
I'm trying to open a simple .rtf file called test in C. I'm using Xcode. My code is:
#include <stdio.h>
#include <stdlib.h>
int main (int argc, const char * argv[]) {
FILE *filePtr;
filePtr = fopen("test.rtf", "r");
if (filePtr == NULL) {
fprintf(stderr, "Can't open \"test\"\n");
exit(EXIT_FAILURE);
}
else {
printf("File open successful\n");
int x;
/* read one character at a time until EOF is reached */
while ((x = fgetc(filePtr)) != EOF) {
printf("%c", x);
}
}
fclose(filePtr);
return 0;
}
I have the test.rtf file in the same directory as my Xcode.proj directory. My output is "File open successful", however I do not get anything read from the file. Am I doing this right? Thanks.
There's nothing wrong with that code at all. I tested it (albeit not in Xcode) with a file and the transcript was:
pax> echo hello >test.rtf
pax> ./qq.exe
File open successful
hello
So the obvious think to ask is what happens when you examine test.rtf? Does it actually have any content? Because, when I do:
pax> rm test.rtf ; touch test.rtf
pax> ./qq.exe
File open successful
I get the same behaviour you observe.
Also try renaming it to test2.rtf temporarily and make sure you get the error. It's possible it may be opening a different copy of the file than what you think (this often happens in Visual C since the directory the program runs in is not always what developers think at first).
It looks right.
As for the lack of output, two possibilities:
Are you sure the file has some content? Maybe ls -l test.rtf or dir test.rft
Possibly it has some control characters which cause the terminal to which it is written to suppress output.
Try moving test.rtf to your build directory. If your project is named MyProject, move it to MyProject/build/Debug/.
I can think of two things that could cause this problem. Either there is an error when calling fgetc, or you are getting output that you don't recognize.
fgetc() will return EOF when the end of the file is reached, or an error occurs. To determine if it's an error, just after your while loop try:
if (ferror(filePtr) != 0) printf("error: %d.\n", errno);
A .rtf file is not a plain text file. It likely contains a bunch of formatting information. You are expecting to see "Hello . . . ". but what you may actually see is something like:
{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf250
{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
{\colortbl;\red255\green255\blue255;}
\margl1440\margr1440\vieww9000\viewh8400\viewkind0
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040
\f0\fs24 \cf0 Hello . . .
And you are just assuming that is GDB output, not your program's output.
Based upon your recent comments, I think you have an empty file test.rtf in the directory your program is run in, and your real test.rtf file is in some other directory. Maybe your fopen() call at some point was fopen("test.rtf", "w"); instead of fopen("test.rtf", "r");, and you later modified it.
To see the directory your program is running in, add the following to your program after the FILE *filePtr; line:
char pwd[512];
if (getcwd(pwd, sizeof pwd) != -1)
printf("In directory %s\n", pwd);
else
fprintf(stderr, "Need bigger buffer, change '512' above\n");
Then, you can open a terminal, do cd <directory>, and test for yourself if the file you want is the file your program is opening.
You probably want this file to be plain text, not rich text. Rich text has a lot of formatting encoded into the file.