I've been trying to run this very simple C code on Ubuntu 20.04LTS
#include<stdio.h>
#include<stdlib.h>
int main()
{
FILE *f;
f=fopen("tree.txt","r");
if(f==NULL){
perror("fopen");
exit(1);
}
//readTree();
return 0;
}
But no matter what I've tried so far fopen still returns this eror:
fopen: No such file or directory
[1] + Done
First thing I assumed was that the program didn't have permission to open the file, but the permissions are set correctly:
ls -la tree.txt
-rw-rw-rw- 1 mor mor 7 mar 26 20:43 tree.txt
Next I tried to change the location of the file to /home or to specify a full path instead of the file name; still the same result
Now comes the part I can't wrap my head around, when running the script under Strace, it appears to work fine , at least for now
execve("./B1", ["./B1"], 0x7ffe586e59b0 /* 26 vars */) = 0
brk(NULL) = 0x55cd150ea000
arch_prctl(0x3001 /* ARCH_??? */, 0x7fff084d4590) = -1 EINVAL (Invalid argument)
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=156877, ...}) = 0
mmap(NULL, 156877, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fcadcd70000
close(3) = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\360q\2\0\0\0\0\0"..., 832) = 832
pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784, 64) = 784
pread64(3, "\4\0\0\0\20\0\0\0\5\0\0\0GNU\0\2\0\0\300\4\0\0\0\3\0\0\0\0\0\0\0", 32, 848) = 32
pread64(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0\t\233\222%\274\260\320\31\331\326\10\204\276X>\263"..., 68, 880) = 68
fstat(3, {st_mode=S_IFREG|0755, st_size=2029224, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fcadcd6e000
pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784, 64) = 784
pread64(3, "\4\0\0\0\20\0\0\0\5\0\0\0GNU\0\2\0\0\300\4\0\0\0\3\0\0\0\0\0\0\0", 32, 848) = 32
pread64(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0\t\233\222%\274\260\320\31\331\326\10\204\276X>\263"..., 68, 880) = 68
mmap(NULL, 2036952, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fcadcb7c000
mprotect(0x7fcadcba1000, 1847296, PROT_NONE) = 0
mmap(0x7fcadcba1000, 1540096, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x25000) = 0x7fcadcba1000
mmap(0x7fcadcd19000, 303104, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x19d000) = 0x7fcadcd19000
mmap(0x7fcadcd64000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1e7000) = 0x7fcadcd64000
mmap(0x7fcadcd6a000, 13528, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fcadcd6a000
close(3) = 0
arch_prctl(ARCH_SET_FS, 0x7fcadcd6f540) = 0
mprotect(0x7fcadcd64000, 12288, PROT_READ) = 0
mprotect(0x55cd14c84000, 4096, PROT_READ) = 0
mprotect(0x7fcadcdc4000, 4096, PROT_READ) = 0
munmap(0x7fcadcd70000, 156877) = 0
brk(NULL) = 0x55cd150ea000
brk(0x55cd1510b000) = 0x55cd1510b000
openat(AT_FDCWD, "tree.txt", O_RDONLY) = 3
exit_group(0) = ?
+++ exited with 0 +++
The openat() call returns a small positive integer, which is normal behavior from what I read so far
Lastly, what really grinds my gears is that the output of Strace above differs from the output I received just a couple minutes before . For some reason I can't seem to recreate that output but the gist of it is this:
-openat() returns 3
- lseek(fd, -9, SEEK_CUR) is called and returns -1 ESPIPE Illegal seek please excuse my syntax here, I'm writing it from memory. Also why is the offset a negative integer? Is that normal?
And why was lseek() called the first couple of times, but not now?
Reading man on lseek here it says that
On Linux, using lseek() on a terminal device fails with the error ESPIPE.
also the error descriptor
ESPIPE fd is associated with a pipe, socket, or FIFO.
I believe the first quote to be unrelated, plenty of threads online with people managing to use fopen() on linux. When it comes to the error descriptor, it is beyond my level of understanding.
renderer1.log:
[2021-03-27 23:08:46.895] [renderer1] [error] Unexpected: The specified task is missing an execution: Error: Unexpected: The specified task is missing an execution
at S.getTaskExecution (/snap/code/59/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:90:48749)
at S.$onDidStartTaskProcess (/snap/code/59/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:90:46905)
at c._doInvokeHandler (/snap/code/59/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:90:10509)
at c._invokeHandler (/snap/code/59/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:90:10201)
at c._receiveRequest (/snap/code/59/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:90:8871)
at c._receiveOneMessage (/snap/code/59/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:90:7673)
at /snap/code/59/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:90:5782
at g.fire (/snap/code/59/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:57:1836)
at p.fire (/snap/code/59/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:65:15443)
at /snap/code/59/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:106:29119
at g.fire (/snap/code/59/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:57:1836)
at p.fire (/snap/code/59/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:65:15443)
at t._receiveMessage (/snap/code/59/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:65:20693)
at /snap/code/59/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:65:17587
at g.fire (/snap/code/59/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:57:1836)
at l.acceptChunk (/snap/code/59/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:65:12808)
at /snap/code/59/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:65:12156
at Socket.E (/snap/code/59/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:106:12375)
at Socket.emit (events.js:315:20)
at addChunk (_stream_readable.js:295:12)
at readableAddChunk (_stream_readable.js:271:9)
at Socket.Readable.push (_stream_readable.js:212:10)
at Pipe.onStreamRead (internal/stream_base_commons.js:186:23)
This is all I could come up with, apparently it's not good enough.
Any and all help is appreciated.
To sum it up, my issue was that the working directory of the.c program and the directory in which i had saved the.txt file were different. There are many ways to get around this issue.
FILE*f; f=fopen("/home/user/Desktop/file.txt","r");
this only works as a test, as it makes the code too rigid(answer provided by @kaylum)
simple code that changes directory to the one specified by the user, opens file with name and mode specified by user; printing cwd using getcwd() (part of the answer provided by @ilkkachu)
//puts cwd in *str and prints cwd if successful, otherwise prints error
void getdir(char *str, unsigned int str_size)
{
if(getcwd(str,str_size)==NULL){
perror("getcwd()");
exit(1);
}else
printf("Current working dir: %s\n",str);
}
//reads directory path and sets it as new working dir
int changeDir()
{
char cwd[256];
printf("New woking dir path= ");
scanf("%s",cwd);
if(chdir(cwd)!=0){
perror("chdir()");
return -1;
}
getdir(cwd,sizeof(cwd));
return 0;
}
int main()
{
FILE *f;
char cwd[256],fmod[5];
getdir(cwd,sizeof(cwd));
//reads new path until an existing one is inputted
while(changeDir()!=0);
printf("File name: ");
scanf("%s",cwd);
printf("File mode: ");
scanf("%s",fmod);
f=fopen(cwd,fmod);
if(f==NULL){
perror("fopen");
exit(1);
}
//reads first line of file and prints it to console
fscanf(f,"%[^\n]",cwd);
printf("%s",cwd);
return 0;
}
Code terminal output:
Current working dir: /home/moro/Documents/TP-Lab
New woking dir path= /home/moro/doesNotExist
chdir(): No such file or directory
New woking dir path= /home/moro/Desktop
Current working dir: /home/moro/Desktop
File name: input.txt
File mode: r
THIS IS A TEST FILE[1] + Done
Go to
Settings>Terminal>Integrated: Cwd
You can specify a start path there
Terminal › Integrated: Cwd An explicit start path where the terminal will be launched, this is used as the current working directory (cwd) for the shell process. This may be particularly useful in workspace settings if the root directory is not a convenient cwd.
There probably are smoother ways to go about this, but for my use case these options are more than good enough. If i find the time i will add more solutions to this answer
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.