Detecting file that isn't there - c

So this is one of the first programs I've ever used some self created error checks however for some reason when I compile this and run it using:
./file test1.txt test2.txt 10
I get absolutely an error suggesting that the output file exists and I've checked the file and it doesn't even when I change the name of the output file (second argument) I get nothing. Anyone who can help? I've been racking my brain for ages now. This is a UNIX homework assignment I'm compiling and running in Gentoo. I have it running in a VB and have a linked folder between my windows and linux OS's.
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#define BUFFT 25
int main (int argc, char *argv[])
{
int count;
int readin;
int writeout;
printf ("This program was called \"%s\".\n",argv[0]);
if (argc > 1)
{
for (count = 1; count < argc; count++)
{
printf("argv[%d] = %s\n", count, argv[count]);
}
}
else
{
perror("The command had no arguments.\n");
exit(-1);
}
// check correct number of arguments parsed //
if (argc == 4)
{
printf("There are the correct number of arguments(4)\n");
}
else
{
perror("Not enough arguments! please try again \n");
exit(-1);
}
//Check original file is there//
int openFD = open(argv[1], O_RDWR);
if (openFD <0)
{
perror("Error unable to read file \n");
exit(-1);
}
//Check existence of output file, if it doesn't exist create it//
int CheckFile = open(argv[2], O_RDONLY);
if (CheckFile < 0)
{
perror("Error output file already exists \n");
exit(-1);
}
else
{
int CheckFile = open(argv[2], O_CREAT);
printf("The file has successfully been created \n");
}
//Create buffer
int bufsize = atoi(argv[3]);
char *calbuf;
calbuf = calloc(bufsize, sizeof(char));
//Read text from original file and print to output//
readin = read(openFD, calbuf, BUFFT);
if (readin < 0){
perror("File read error");
exit(-1);
}
writeout = write(openFD,bufsize,readin);
if (writeout <0){
perror("File write error");
exit(-1);
}
return 0;
}

The open call for HANDLE CheckFile is printing Error File Exists. This is your problem. You are printing out the wrong statement when Output File Is Not Found and moreover you are exiting which prevents the code to create any.
int CheckFile = open(argv[2], O_RDONLY);
if (CheckFile < 0)
{
//Means the file doesn't exist
int CheckFile = open(argv[2], O_CREAT);
// Check for errors here
}
And why are you trying to do this::
writeout = write(openFD,bufsize,readin);
when your HANDLE TO OUTPUT FILE IS CheckFile

int CheckFile = open(argv[2], O_RDONLY);
if (CheckFile < 0)
{
perror("Error output file already exists \n");
A negative return from open means that the file could not be opened, most likely because it does not exist ... it does not mean that the file already exists. Failing to open the input file certainly does not mean that the output file already exists. Please check your code more carefully for obvious errors, e.g.,
int CheckFile = open(argv[2], O_CREAT);
printf("The file has successfully been created \n");
Here you don't check the return code.

Take a look at this fragment of your code:
int CheckFile = open(argv[2], O_RDONLY);
if (CheckFile < 0)
{
perror("Error output file already exists \n");
exit(-1);
}
You are saying trying to open a file in READ ONLY MODE. From what I read in your question, it's not an error if the file doesn't exist, but in the code you are validating the opposite, if the file doesn't exists, throw an error (in fact your message error is incorrect here).
Double check your logic and you will find your solution.

Related

UNIX shell I/O redirection [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I am trying to implement a LINUX shell in C but when I am trying to run a command like this : sort -u < in.txt > out.txt it says : sort: cannot read: '<': No such file or directory . I also tried other commands like ls -l > out.txt etc but it keep telling me the same thing. Here is my code :
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <sys/types.h>
#define LENGTH 1024
int main(){
char line[LENGTH];
char* argv[100];
char* path= "/bin/";
char fullPath[30];
int option;
char* inputFile;
char* outputFile;
while(1){
printf("mysh3>");
if(!fgets(line,LENGTH,stdin)){
break;
}
size_t length = strlen(line);
if(line[length-1]=='\n')
line[length-1] = '\0';
}
char* token;
token = strtok(line," ");
int i = 0;
while(token!=NULL){
argv[i]=token;
token = strtok(NULL," ");
i++;
}
if(argv[1]==">"){
option=1;
outputFile=argv[2];
}
else if(argv[2]==">"){
option = 1;
outputFile=argv[3];
}
else if(argv[1]=="<" && argv[3]==">"){
option=2;
inputFile=argv[2];
outputFile=argv[4];
}
else if(argv[2]=="<" && argv[4]==">"){
option=2;
inputFile=argv[3];
outputFile=argv[5];
}
else if(argv[1]=="<" && argv[3]==">>"){
option=3;
inputFile=argv[2];
outputFile=argv[4];
}
else if(argv[2]=="<" && argv[4]==">>"){
option=3;
inputFile=argv[3];
outputFile=argv[5];
}
argv[i]=NULL;
strcpy(fullPath, path);
strcat(fullPath, argv[0]);
for(int i = 0; i < strlen(fullPath); i++){
if(fullPath[i]=='\n'){
fullPath[i]='\0';
}
}
int ret=forkEx2(argv,inputFile,outputFile,fullPath,option);
if(ret==-1) {
return -1;
}
int forkEx2(char* argv[],char* inputFile,char* outputFile,char
fullPath[],int option){
int fd;
pid_t pid,waitPid;
pid = fork();
if(pid<0){
perror("ERROR: Fork failed.\n");
return -1;
}
else if(pid==0){
if(option==1){
fd=open(outputFile,O_CREAT | O_TRUNC | O_WRONLY, 0600); //if the file does not exist the system create it. Clear all data from the file. Open the file for write only.Store its file descriptor in fd
dup2(fd,STDOUT_FILENO); //replace the standar out with the file
close(fd);
}
else if(option==2){
fd=open(inputFile,O_RDONLY,0600); //open the file for read only
dup2(fd,STDIN_FILENO); //replace the standar in with the file
close(fd);
fd=open(outputFile,O_CREAT | O_TRUNC | O_WRONLY, 0600); //if the file does not exist the system create it. Clear all data from the file. Open the file for write only
dup2(fd,STDOUT_FILENO); //replace the standar out with the file
close(fd);
}
else if(option==3){
fd=open(inputFile,O_RDONLY,0600); //open the file for read only
dup2(fd,STDIN_FILENO); //replace the standar in with the file
close(fd);
fd=open(outputFile, O_APPEND | O_WRONLY, 0600); //append at the end of the file. Open the file for write only
dup2(fd,STDOUT_FILENO); //replace the standar out with the file
close(fd);
}
execvp(fullPath,argv);
perror("ERROR: Child should never arrive here.\n");
}
else{
waitPid = wait(&waitPid);
if (waitPid == -1) {
perror("ERROR: Waitpid failed.\n");
return -1;
}
printf("Parent: Finished pid %d.\n", waitPid);
}
}
}
Any help is appreciated.
let's take that case (it's the same in all cases):
else if(argv[2]=="<" && argv[4]==">"){
option=2;
inputFile=argv[3];
outputFile=argv[5];
}
First, you're comparing strings using ==: that doesn't work. You have to use strcmp or you're comparing the pointers.
Then, you're extracting input file & output file all right, but you forget to remove the redirection arguments from argv. You have to filter them out (by shifting the rest of the argument array each time you encounter one redirection argument)
Aside: you should initialize your argv array or you may meet undefined behaviour if there are not enough arguments.

C - Declare a file in function parameters

so here is my problem :
int isopen()
{
int fd;
fd = open("myfile", O_RDONLY);
if (fd == 0)
printf("file opening error");
if (fd > 0)
printf("file opening success");
return(0);
}
int main(void)
{
isopen();
return(0);
}
Is use this code to check if this the open command worked, as i'm just starting to lurn how to use it.
Basically this code is working just fine, but I would like to declare the file I would like to open directly in the parameters of my function isopen.
I saw some other posts using main's argc and argv, but I really need to declare my file in the parameters of my function isopen, not using argc & argv.
Is it even possible ?
Thank you for your help, I'm quite lost here.
Your question is unclear, but maybe you want this:
int isopen(const char *filename)
{
int fd;
fd = open(filename, O_RDONLY);
if (fd < 0) //BTW <<<<<<<<<<<< fd < 0 here !!
printf("file opening error");
else // else here
printf("file opening success");
return(0);
}
int main(void)
{
isopen("myfile");
return(0);
}
BTW, the isopen function as it stands here is still pretty useless as it just opens the file and throwing away fd.
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int isOpen(char *filename)
{
return open(filename, O_RDONLY);
}
int main()
{
printf("%d\n", isOpen("/home/viswesn/file1.txt"));
printf("%d\n", isOpen("file2.txt"));
return 0;
}
Output
viswesn#viswesn:~$ cat /home/viswesn/file1.txt
hello
viswesn#viswesn:~$
viswesn#viswesn:~$ cat /home/viswesn/file2.txt
cat: /home/viswesn/file2.txt: No such file or directory
viswesn#viswesn:~$
viswesn#viswesn:~$ ./a.out
3 <---------- File exist and it give file descriptor number '3'
STDIN-0, STDOUT-1, STDERR-2 are reserved and
next file opened will start with 3 and it keeps going
-1 <--------- File not found; so open gives -1 as error

System calls in C (File Descriptor)

follwing code has written to open a file and write data to terminal using sysyem calls in linux.
To read the value of the file descriptor (fd) it should assign a value. As we know in if else statement, from if part else part or else if part one part will implement at a time. So according to following code fd will have a value only at else if line. But when I pass a file name and run this program it opens the file. File opening is happen in while loop from read(() system call. But while loop is in else part and since file descriptor can't have any value theoretically. So how does the read function get recognize the file exactly? This is confusing me.
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#define SIZE 10
int main(int argc, char *argv[])
{
int fd,n;
char buff[SIZE];
if(argc != 2)
{
printf("USAGE : %s\n",argv[0] );
exit(1);
}
else if ((fd = open(argv[1],0)) == -1)
{
perror("STATUS");
exit(1);
}
else
{
while((n = read(fd,buff,SIZE)) > 0)
{
write(1,buff,SIZE);
}
close(fd);
}
}
Following happens here:
Let's suppose the program is started with xyz.txt on the command line and let's suppose the xyz.txt file does exist:
if(argc != 2)
{
// we don't get here because argc == 2
printf("USAGE : %s\n",argv[0] );
exit(1);
}
else if ((fd = open(argv[1],0)) == -1) // the statement in the if clause will therefore
// be executed, fd will be something different
// from -1 because open succeeded
{
perror("STATUS"); // therefore we dont ge here either
exit(1);
}
else
{ // instead we get here and
while((n = read(fd,buff,SIZE)) > 0) // everything works as expected
{
write(1,buff,SIZE);
}
close(fd);
}

beginner in C under linux. write function doesn't work properly

I'm trying to write a C program, that make user able to write stuff in a file. My Problem is that after making and running the program the file stay empty ?? any idea how can I solve this.
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
// the user should give a file to write the file
int main (int argc , char**argv)
{
int fd; // file descriptor
char ret; // the character
int offset;
if(argc != 2) {
printf("You have to give the name or the path of the file to work with \n");
printf("Exiting the program \n")
return -1;
}
fd = open (argv[1], O_WRONLY/*write*/|O_CREAT/*create if not found */, S_IRUSR|S_IWUSR/*user can read and write*/);
if (fd == -1) {
printf("can'T open the file ");
return -1;
}
printf("At wich position you want to start ");
scanf("%d",&offset);
lseek(fd,offset,SEEK_SET);
while(1) {
ret = getchar();
if(ret == '1') {
printf("closing the file");
close (fd);
return 1;
}
else
write (fd,red, sizeof(char));
}
return 0;
}
thanks in advance for you help.
I have made some changes,this should work:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
int main (int argc , char**argv)
{
int fd; // file descriptor
char ret; // the character
int offset;
if(argc != 2){
printf("You have to give the name or the path of the file to work with \n");
printf("Exiting the program \n"); **//There was ';' missing here**
return -1;
}
fd = open (argv[1], O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR);
if (fd == -1) {
printf("can'T open the file ");
return -1;
}
printf("At wich position you want to start ");
scanf("%d",&offset);
lseek(fd,offset,SEEK_SET);
while(1){
ret = getchar();
if(ret == '1'){
printf("closing the file");
close (fd);
return 1;
}
else
write (fd,&ret, sizeof(char)); **//red has been changed to &ret**
}
return 0;
}
One error I can notice, the call of write function:
write (fd,red, sizeof(char));
should be:
write (fd, &red, sizeof(char));
You forgot & before red, write need address.
syntax of write: int write( int handle, void *buffer, int nbyte );
This will cause an undefined behavior in your code at run time
Edit: in write function you are using red that is not defined, I think it should be ret variable in your code. correct it as write (fd, &ret, sizeof(char));
second, you forgot ; after printf("Exiting the program \n") in if, but I also think its mistake while posting question as you says you are getting run time error.
side note: If you are using gcc compiler then you can use gcc -Wall -pedantic to generate warnings
It should be:
write (fd,&ret, sizeof(char));
write takes the pointer to the memory position, and since ret is a single char, you need to pass a pointer to it.

Why does writing to a file descriptor after the target file has been deleted succeed?

code:
int main(int argc, char **argv)
{
int fd = open("test.txt", O_CREAT|O_RDWR, 0200|0400);
if(fd == -1)
{
printf("failure to oepn");
exit(-1);
}
int iRet = write(fd, "aaaaaaaaaa", 10);
if(iRet == -1)
{
printf("failure to writer");
exit(-1);
}
sleep(10);
printf("You must remove");
iRet = write(fd, "bbbbbbbbbb", 10);
if(iRet == -1)
{
printf("failure to after writer");
exit(-1);
}
exit(0);
}
during the sleep(), you delete the test.txt, but the process write successful!why?
if a log ”Singleton“ instance, you remove the file on the disk.write is successful, but you can get nothing.
class log
{
public:
void loggerWriter(std::string str);
int fd;
};
log::log(std::string filename):fd(-1)
{
fd = open(filename.c_str(), O_CREAT|)
//...
}
log::loggerWriter(std::string str)
{
writer(fd, str.c_str(), str.size());
}
int main()
{
log logger("text.txt");
//...
//I want to know the text.txt the text.txt have delete on the disk or not.
//if delete i can create another file to log.
}
"unlink" cann't solve this problem.
The manual page for unlink(2) states clearly:
unlink() deletes a name from the file system. If that name was the
last link to a file and no processes have the file open the file is
deleted and the space it was using is made available for reuse.
If the name was the last link to a file but any processes still have
the file open the file will remain in existence until the last file
descriptor referring to it is closed.
As caf excellently notes in the comments:
The write() is successful because it writes to the file, which still
exists at this point even though it no longer has a name. The filename
and the file itself are distinct, and have separate lifetimes.

Resources