As everything is file in Linux I would like to print to opened console in terminal window.
I have opened console in Linux and have written command tty. In output I have:
/dev/pts/25
This is the program that copies everything from foo file to bar and console:
/* Trivial file copy program using low-level I/O */
#include <fcntl.h>
#include <stdlib.h>
#define BSIZE 16384
void main()
{
int fin, fout,con; /* Input and output handles */
char buf[BSIZE];
int count;
if ((con = open("/dev/pts/2", O_WRONLY)) < 0) {
perror("open con ");
exit(1);
}
if ((fin = open("foo", O_RDONLY)) < 0) {
perror("foo");
exit(1);
}
if ((fout = open("bar", O_WRONLY | O_CREAT, 0644)) < 0) {
perror("bar");
exit(2);
}
while ((count = read(fin, buf, BSIZE)) > 0)
{
write(fout, buf, count);
write(con, buf, count);
}
close(fin);
close(fout);
close(con);
}
Unfortunately nothing is written in console window while bar contains needed information. How to write to console terminal window?
I have opened console in Linux and have written command tty. In output I have:
/dev/pts/25
This is program that coppyes evrything from foo file to bar and console:
…
if ((con = open("/dev/pts/2", O_WRONLY)) < 0) {
…
Your program opens just a device pts/2 different from pts/25 which you say is your console.
Related
So I'm working on the server side of my program right now, and I want to do the following:
1) open a file in read/write mode
2) append a word (WORD) to the end of the file
3) [I believe I have all of this part down already] open a pipe, create a child process, have it read directly from the file (file descriptor), execute a command, and send the result into the write/output of the pipe. The parent process reads from the read/input of the pipe and puts the info into a buffer to send back to the client.
What I'm having trouble with is the appending part. I'm pretty sure it appends to the file (with a newline in between the existing text and my WORD) because when I directly open the text file it's there. But when I try to print it from my buffer, it's not there. I have tried closing the file descriptor after writing and reopening and it's not there. I've tried strcat instead of writing to the file descriptor and it's not there.
#define WORD "WORD"
#define BUFFERLENGTH 512
char buffer[BUFFERLENGTH];
int fileDesc = open (filePath, O_RDWR|O_APPEND, 0660);
if (fileDesc <= 0){
write(clientDesc, ERRORMSG, BUFFERLENGTH);
exit(EXIT_FAILURE);
}
read(fileDesc,buffer,BUFFERLENGTH);
long length = lseek(fileDesc,0,SEEK_END);
int status = write(fileDesc,WORD,sizeof(WORD)-1);
read(fileDesc, buffer, BUFFER_LEN+1);
printf("new text: %s\n", buffer); //WORD does not show up at the end of file as intended
Is there something I'm really misunderstanding?
Perhaps I don't fully understand how open(), read(), write(), and lseek() work, but if anyone could help explain to me why this isn't working as intended that'd be greatly appreciated. I've been struggling with this for the past week and the number of tabs I currently have open to searching for a solution is tragic.
After your write() call you're going to be at the end of the file, so read() isn't going to be able to read anything. You'll need to lseek() to a point earlier in the file if you want to be able to read anything from it.
You should be checking the return from read() (and almost all other system calls, for that matter) and use perror() or similar in the case of error, and this will do wonders for helping you to understand what's going on when you see behavior you don't expect.
Modifying your program:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#define WORD "WORD"
#define BUFFERLENGTH 512
int main(void)
{
char * filePath = "testfile.txt";
char buffer[BUFFERLENGTH] = {0};
// Open file.
int fd = open(filePath, O_RDWR | O_APPEND, 0660);
if (fd < 0) {
perror("couldn't open file");
return EXIT_FAILURE;
}
// Write word to end.
int status = write(fd, WORD, strlen(WORD));
if ( status < 0 ) {
perror("couldn't write");
return EXIT_FAILURE;
}
// Seek to start of file.
long length = lseek(fd, 0, SEEK_SET);
if ( length < 0 ) {
perror("couldn't lseek");
return EXIT_FAILURE;
}
// Read contents of file.
status = read(fd, buffer, BUFFERLENGTH - 1);
if ( status < 0 ) {
perror("couldn't read");
return EXIT_FAILURE;
}
// Print buffer.
printf("file contents: %s\n", buffer);
return 0;
}
yields:
paul#mac:scratch$ touch testfile.txt
paul#mac:scratch$ ./file
file contents: WORD
paul#mac:scratch$ ./file
file contents: WORDWORD
paul#mac:scratch$ ./file
file contents: WORDWORDWORD
paul#mac:scratch$ ./file
file contents: WORDWORDWORDWORD
paul#mac:scratch$
If you want to actually see only the new contents, then you'll need to lseek() to some point other than the start of the file. Since a successful write() will return the number of bytes written, you can use this value to offset back from the end of the file:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#define BUFFERLENGTH 512
int main(int argc, char * argv[])
{
if ( argc < 2 ) {
fprintf(stderr, "you need to enter a word argument\n");
return EXIT_FAILURE;
}
char * filePath = "testfile.txt";
char buffer[BUFFERLENGTH] = {0};
// Open file.
int fd = open(filePath, O_RDWR | O_APPEND, 0660);
if ( fd < 0 ) {
perror("couldn't open file");
return EXIT_FAILURE;
}
// Write word to end.
int status = write(fd, argv[1], strlen(argv[1]));
if ( status < 0 ) {
perror("couldn't write");
return EXIT_FAILURE;
}
// Seek to point before last write.
long length = lseek(fd, -status, SEEK_END);
if ( length < 0 ) {
perror("couldn't lseek");
return EXIT_FAILURE;
}
// Read from there to end of file.
status = read(fd, buffer, BUFFERLENGTH - 1);
if ( status < 0 ) {
perror("couldn't read");
return EXIT_FAILURE;
}
// Print buffer.
printf("new text: %s\n", buffer);
return 0;
}
yielding:
paul#mac:scratch$ rm testfile.txt
paul#mac:scratch$ touch testfile.txt
paul#mac:scratch$ ./file2 these
new text: these
paul#mac:scratch$ ./file2 are
new text: are
paul#mac:scratch$ ./file2 some
new text: some
paul#mac:scratch$ ./file2 words
new text: words
paul#mac:scratch$ cat testfile.txt
thesearesomewordspaul#mac:scratch$
I'm trying to write characters in a text file on my Macbook Air, but it seems not to be working.
I tried compiling both via Xcode and Terminal.
But the results are same:
File Descripter: 3
write() Error!
Here is the code.
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
void Error_handling(char* message);
int main() {
int fd;
char buf[] = "Let's go! \n";
fd = open("data.txt", O_CREAT|O_RDONLY|O_TRUNC);
if (fd == -1)
Error_handling("open() Error! \n");
printf("File Descripter: %d \n", fd);
if(write(fd, buf, sizeof(buf))==-1)
Error_handling("write() Error! \n");
close(fd);
return 0;
}
void Error_handling(char* message)
{
fputs(message, stderr);
exit(1);
}
You open file with O_RDONLY and then try to write, of course it reports error.
And as comments suggested the right open variant should be:
fd = open("data.txt", O_CREAT|O_WRONLY|O_TRUNC, 0600);
Your file is opened in read only mode, which naturally prevents you from writing to it.
fd = open("data.txt", O_CREAT|O_RDONLY|O_TRUNC);
// ^ <- Your problem is here
Fix it by using
fd = open("data.txt", O_CREAT|O_WRONLY|O_TRUNC, S_IWRITE);
My objective is to make an IPC between a child and parent through a FIFO. The child should run
execl ("/bin/cat", "cat", "/etc/passwd", (char *)0);
redirect its output to the parents input and the parent should run this command:
cut -l : -f 1
and output this to command line.
Right now, I've successfully linked my FIFO and redirected the output of my child process to the input of the parent. I've done multiple tests and that connection is working properly. The problem is with the execl for the cut, which should look something like this:
execlp("/bin/cut", "cut", "-l:", "-f", "1", NULL);
but I'm pretty sure it isn't.
int cut(){
//
int myfifo;
char buf[MAX_BUF];
printf("\nCut opening FIFO");
if((myfifo = open("/tmp/myfifo", O_RDONLY | O_TRUNC))<0){
perror("open FIFO at cut");
quit(EXIT_FAILURE);}
else{printf("\nCut has FIFO opened and is reading\n");}
//read(myfifo, buf, MAX_BUF); outputting buf goes as supposed to
if( dup2(myfifo, 0) < 0 ){
perror("dup2 at cut");
quit(EXIT_FAILURE);}
//read(STDIN_FILENO, buf, MAX_BUF);
close(myfifo);
execlp("/bin/cut", "cut", "-l:", "-f", "1", NULL);
//this is for testing buf, but i guess the program shouldn't even get here
printf("\nCut has received: %s\nAnd is closing FIFO", buf);
return -1;
}
int cat(){
int myfifo;
//OPEN FIFO
printf("\nCat opening FIFO");
if( (myfifo = open("/tmp/myfifo", O_WRONLY | O_TRUNC) )<0){
perror("open FIFO at cat");
quit(EXIT_FAILURE);
}
else{
printf("\nCat has opened FIFO");
//WRITE OUTPUT OF "cat \etc\passwd" TO FIFO
dup2(myfifo, 1);
execl ("/bin/cat", "cat", "/etc/passwd", (char *)0);
}
close(myfifo);
return 0;
}
The main currently only creates the fifo (mkfifo), forks() and calls the function.
My problem could with the stdin of the parent (running cut), but I don't think so, or maybe I'm assuming execl() reads directly from the stdin and It doesn't.
I think it's really bcause I'm not writing the "cut" through execl() properly.
Any corrections to the code, or even the way I expressed some ideas can indicate that I don't understand something properly, would be very appreciated.
Thank you for helping
As noted in a comment, the cut command under GNU and BSD (and POSIX) does not support a -l option; the option you need is -d for delimiter.
This code works for me. On my machine, /bin/cat is correct, but /usr/bin/cut is correct (not /bin/cut), so I had to compile with:
$ rmk cutcat UFLAGS=-DCUT_CMD=/usr/bin/cut && ./cutcat
gcc -O3 -g -std=c11 -Wall -Wextra -Werror -DCUT_CMD=/usr/bin/cut cutcat.c -o cutcat
$
That uses a custom variant of make (called rmk) and a custom makefile, but the location of the cut command is specified on the command line via the UFLAGS (user flags) macro. The STRING and EXPAND macros in the C code are a nuisance, but not as much of a nuisance as trying to get double quotes past the shell that invokes make (or rmk) and then the shell that make invokes to run the compiler.
The code:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/stat.h>
#ifndef CUT_CMD
#define CUT_CMD /bin/cut
#endif
#ifndef CAT_CMD
#define CAT_CMD /bin/cat
#endif
#define EXPAND(x) #x
#define STRING(x) EXPAND(x)
static const char cut_cmd[] = STRING(CUT_CMD);
static const char cat_cmd[] = STRING(CAT_CMD);
static inline void quit(int status) { exit(status); }
enum { MAX_BUF = 4096 };
static void cut(void)
{
int myfifo;
printf("\nCut opening FIFO");
if ((myfifo = open("/tmp/myfifo", O_RDONLY | O_TRUNC)) < 0)
{
perror("open FIFO at cut");
quit(EXIT_FAILURE);
}
printf("\nCut has FIFO opened and is reading\n");
if (dup2(myfifo, 0) < 0)
{
perror("dup2 at cut");
quit(EXIT_FAILURE);
}
close(myfifo);
execlp(cut_cmd, "cut", "-d:", "-f", "1", NULL);
fprintf(stderr, "Failed to execute %s\n", cut_cmd);
exit(1);
}
static
void cat(void)
{
int myfifo;
printf("\nCat opening FIFO");
if ( (myfifo = open("/tmp/myfifo", O_WRONLY | O_TRUNC) ) < 0)
{
perror("open FIFO at cat");
quit(EXIT_FAILURE);
}
printf("\nCat has opened FIFO");
dup2(myfifo, 1);
close(myfifo);
execl(cat_cmd, "cat", "/etc/passwd", (char *)0);
fprintf(stderr, "Failed to execute %s\n", cat_cmd);
exit(1);
}
int main(void)
{
mkfifo("/tmp/myfifo", 0600);
if (fork() == 0)
cat();
else
cut();
/*NOTREACHED*/
fprintf(stderr, "You should not see this message\n");
return 0;
}
Sample output:
Much truncated
…
nobody
root
daemon
_uucp
_taskgated
_networkd
…
The code is really not very different from what you had. I removed some clutter. I did ensure that close(myfifo) was executed by cat(); it wasn't in the original. It might be significant.
update 20-12-2014: This problem has been solved, see the bottom of the question for working code.
Design
There are four clients that process some data and then passes it to a server process over a named pipe (FIFO).
Problem
When running the server outside of gdb (not stepping in gdb also gives the same problem) only one pipe is read. Select returns 1 and FD_ISSET only reacts to one pipe (and it stays the same pipe during execution).
Looking into /proc/[PID]/{fd,fdinfo} shows that the other pipes are still open and haven't been read. The pos field in fdinfo is 0).
The Question
What do I need to change to read from all the four pipes in an interleaved fashion?
Test
To simulate the client I use a 12MByte random file that is catted onto the named pipe.
The random file is generated with:
dd if=/dev/urandom of=test.bin bs=1024 count=$((1024*12))
And then executed as (each in a separate terminal and in the following order)
terminal 1:
./server.out
terminal 2:
cat test.bin > d0
terminal 3:
cat test.bin > d1
terminal 4:
cat test.bin > d2
terminal 5:
cat test.bin > d3
Makefile
server:
gcc server.c -o server.out -g -D _DEFAULT_SOURCE -Wall --std=c11
Source
The clients are called dongles.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/select.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#define NR_OF_DONGLES 4
int do_something(int fd);
int main()
{
fd_set read_fd_set;
FD_ZERO(&read_fd_set);
int dongles[NR_OF_DONGLES];
/*Create FIFO */
for(int i = 0; i < NR_OF_DONGLES; i++)
{
char name[255];
snprintf(name, sizeof(name), "d%d", i);
if(mkfifo(name, 0666) == -1)
{
fprintf(stderr, "Failed to create fifo %s \t Error: %s", name, name);
exit(EXIT_FAILURE);
}
int dongle = open(name, O_RDONLY);
if(dongle > 0)
{
fprintf(stderr,"set dongle %s\n", name);
FD_SET(dongle, &read_fd_set);
dongles[i] = dongle;
}
else
{
fprintf(stderr, "failed to open: %s\nerror: %s\n", name, strerror(errno));
exit(EXIT_FAILURE);
}
}
int closed = 0;
int isset[NR_OF_DONGLES];
memset(isset, 0, sizeof(isset));
while(closed < NR_OF_DONGLES)
{
int active;
if((active = select (FD_SETSIZE , &read_fd_set, NULL,NULL,NULL)) < 0)
{
fprintf(stderr, "select failed\n errno: %s\n",strerror(errno));
exit(EXIT_FAILURE);
}
fprintf(stderr, "active devices %i\n", active);
for(int i = 0; i < NR_OF_DONGLES; ++i)
{
int dongle = dongles[i];
if(FD_ISSET(dongle, &read_fd_set))
{
isset[i] += 1;
int size = do_something(dongle);
fprintf(stderr, "round %i \tdongle %i \tread %i bytes\n", isset[i],i, size);
if(size == 0)
{
if(close(dongle) == -1)
{
fprintf(stderr,"Could not close dongle %i\nError: %s\n",
i,strerror(errno));
}
closed += 1;
fprintf(stderr, "closed dongle %i \t number of closed dongles %i\n",
i, closed);
FD_CLR(dongle, &read_fd_set);
}
}
}
}
exit(EXIT_SUCCESS);
}
#define BLOCK_SIZE (8*1024)
/*
* If the size is zero we reached the end of the file and it can be closed
*/
int do_something(int fd)
{
int8_t buffer[BLOCK_SIZE];
ssize_t size = read(fd, buffer, sizeof(buffer));
if(size > 0)
{
//Process read data
}
else if(size == -1)
{
fprintf(stderr, "reading dongle failed\nerrno: %s", strerror(errno));
return -1;
}
return size;
}
The Solution
kestasx's solution worked for me. The watchlist (read_fd_set) needs to be reinitialized before a call to select.
Source code
while(closed < number_of_dongles)
{
/*Reinitialize watchlist of file descriptors.*/
FD_ZERO(&read_fd_set);
for(int i = 0; i < number_of_dongles; i++)
{
int dongle = dongles[i];
/*if fd == -1 the pipe has been closed*/
if(dongle != -1)
{
FD_SET(dongle, &read_fd_set);
}
}
int active = select (FD_SETSIZE , &read_fd_set, NULL,NULL,NULL);
if(active < 0)
{
fprintf(stderr, "select failed\n errno: %s\n",strerror(errno));
exit(EXIT_FAILURE);
}
//fprintf(stderr, "active devices %i\n", active);
for(int i = 0; i < number_of_dongles; ++i)
{
int dongle = dongles[i];
/*Check if the current dongle fd has data in the FIFO*/
if(FD_ISSET(dongle, &read_fd_set))
{
isset[i] += 1;
int size = transfer_dongle_data(dongle);
// fprintf(stderr, "round %i \tdongle %i \tread %i bytes\n", isset[i],i, size);
if(size == 0)
{
if(close(dongle) == -1)
{
fprintf(stderr,"Could not close dongle %i\nError: %s\n",
i,strerror(errno));
}
closed += 1;
fprintf(stderr, "closed dongle %i \t number of closed dongles %i\n",
i, closed);
FD_CLR(dongle, &read_fd_set); //could be removed
/*notify that the pipe is closed*/
dongles[i] = -1;
}
}
}
}
You can try to run Your code via strace (truss on Solaris, ktrace/kdump on FreeBSD). For me it stalls on open("d0", O_RDONLY). So the server dosn't create all pipes before (other pipes most likely are created by cat).
if(dongle)... after open is incorrect: in case of failure open() returns -1, not 0.
Because of this, I think Your program is not working with files You expect (only one pipe is openned correctly).
One more issue ir related to select() use. You should reinitialize read_fd_set before each call to select(), because after each select() call only descriptors, which have data are left marked, others are cleared.
After some tinkering, I got it. On my MacOSX open(...) would block until there was actually something on the FIFO. Consider the program below; it worked as soon as you start feeding data into d0, d1 and so on. But until then, the output of the program was only:
Creating dongle d0
Creating dongle d1
Creating dongle d2
Creating dongle d3
Opening dongle d0
So I pulled up the manpage for open() and lo and behold - there's a flag O_NONBLOCK. With that added in, the following code works like a charm. FYI, POSIX doesn't say that opening a FIFO should block, but I found comments that some implementations do.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <stdarg.h>
#include <errno.h>
#include <sys/select.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#define NR_OF_DONGLES 4
#define BLOCK_SIZE (8*1024)
// Prints error and stops program
int error(char const *fmt, ...) {
va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
exit(1);
}
// Alternative for printf() that flushes stdout
void msg(char const *fmt, ...) {
va_list args;
va_start(args, fmt);
vprintf(fmt, args);
fflush(stdout);
}
// Reads an open readable fd
int do_something(int fd) {
int8_t buffer[BLOCK_SIZE];
ssize_t size = read(fd, buffer, sizeof(buffer));
if(size > 0)
msg("Got data from fd %d, length %ld\n", fd, size);
else if (size == -1)
error("Reading dongle fd %d failed: %s\n", fd, strerror(errno));
else
msg("Dongle with fd %d signals EOF\n", fd);
return size;
}
int main() {
int dongles[NR_OF_DONGLES];
// Create the dongles, open, add to list of open fd's
for (int i = 0; i < NR_OF_DONGLES; i++) {
char name[255];
snprintf(name, sizeof(name), "d%d", i);
msg("Creating dongle %s\n", name);
if (mkfifo(name, 0666) == -1 && errno != EEXIST)
error("Failed to create fifo %s: %s\n", name, strerror(errno));
}
for (int i = 0; i < NR_OF_DONGLES; i++) {
char name[255];
snprintf(name, sizeof(name), "d%d", i);
msg("Opening dongle %s\n", name);
/* ****************************************
* Here it is, first test was with
* int fd = open(name, O_RDONLY);
* which blocked at the open() call
*******************************************/
int fd = open(name, O_RDONLY | O_NONBLOCK);
if (fd < 0)
error("Cannot open dongle %s: %s\n", name, strerror(errno));
dongles[i] = fd;
}
int closed = 0;
while (closed < NR_OF_DONGLES) {
msg("Closed dongles so far: %d\n", closed);
// Add dongle fd's to select set, unless the fd is already closed
// which is indicated by fd == -1
fd_set read_fd_set;
FD_ZERO(&read_fd_set);
for (int i = 0; i < NR_OF_DONGLES; i++)
if (dongles[i] > 0)
FD_SET(dongles[i], &read_fd_set);
// Wait for readable fd's
int active;
if ( (active = select (FD_SETSIZE , &read_fd_set, 0, 0, 0)) < 0 )
error("Select failure: %s\n", strerror(errno));
msg("Active dongles: %d\n", active);
for (int fd = 0; fd < FD_SETSIZE; fd++)
if (FD_ISSET(fd, &read_fd_set)) {
msg("Fd %d is readable\n", fd);
int size = do_something(fd);
if (!size) {
// Fd signals EOF. Close dongle, remove from array
// of open fd's by setting to -1
msg("Fd %d signals EOF\n", fd);
if (close(fd) < 0)
error("Failure to close fd %d: %s\n",
fd, strerror(errno));
for (int i = 0; i < NR_OF_DONGLES; i++)
if (dongles[i] == fd)
dongles[i] = 0;
// Update closed fd counter
closed++;
}
}
}
exit(0);
}
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.