File Descriptors, open() returns zero - c

i open a file and want to write something in it. The problem is that the fd2 for some reason is 0. Instead of writting in the file, it writes on terminal. I dont close(0) anywhere in my code. Why do i get fd = 0 and not for example 3. The reason that writes on terminal is that the value of fd is zero? I know that fd = 0 is for standard input,
Any Ideas? Thank you.
if ((fd2 = open(logFile, O_RDWR |O_APPEND | O_CREAT , 0666) == -1))
DieWithError("open() failed");
printf("FD2 = %d",fd2); //returns me zero
bzero(tempStr, sizeof(tempStr));
bzero(hostname, sizeof(hostname));
gethostname(hostname, sizeof(hostname));
sprintf(tempStr, "\n%sStarting FTP Server on host %s in port %d\n", ctime(&currentime), hostname, port);
if (write(fd2, tempStr, strlen(tempStr)) == -1)
DieWithError("write(): failed");

Your conditional is off. Mind the parentheses. It should be:
if ((fd2 = open(logFile, O_RDWR |O_APPEND | O_CREAT , 0666)) == -1)
// ^^^ ^^^
Sometimes it might be best not to outsmart yourself:
int fd = open(...);
if (fd == -1) { DieWithError(); }

This is wrong.
if ((fd2 = open(logFile, O_RDWR |O_APPEND | O_CREAT , 0666) == -1))
You want this.
if ((fd2 = open(logFile, O_RDWR |O_APPEND | O_CREAT , 0666)) == -1)
It's hard to see because the line is so long, but the parentheses are in the wrong place. In short,
if (( fd2 = open(...) == -1 )) // your code
if (( fd2 = (open(...) == -1) )) // equivalent code
if (( (fd2 = open(...)) == -1) )) // correct code
If the line is so long, best to keep it out of the if...
#include <err.h>
fd2 = open(...);
if (fd2 < 0)
err(1, "open failed");

Related

Why i cannot read from file thought it contains content?

I'm trying to create a function that duplicates a file given a file descriptor and a file name:
int filedup(int fd1, char *cpyfile)
{
int fd;
size_t rd;
char buff;
if (fd1 < 0 || fd1 > OPEN_MAX)
return (-1);
if (!validfname(fname))
return (-1);
fd = open(cpyfile, O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd == -1)
return (-1);
rd = read(fd1, &buff, 1);
while (rd > 0)
{
write(fd, &buff, 1);
rd = read(fd1, &buff, 1);
}
close(fd);
return (0);
}
int main(void)
{
int fd;
fd = open("/tmp/cpyfromfile", O_RDWR | O_CREAT | O_TRUNC, 0644);
if (fd == -1)
return (-1);
putstr_fd(strdup("hello world\n"), fd);
filedup(fd, "cpyfile");
close(fd);
return (0);
}
I tried to debug it, and the problem was rd == 0 even though the file contains data.
$ cat ./cpyfile
$ (nothing)
I'm not sure what's the problem ? what am i doing wrong ?

Redirecting stderr in C

I'm writing a simple shell in C and encountered a minor problem.
I have the following function:
int execStdErr(char** parsedArguments, int numberOfArgs) {
fflush(stderr);
int fd;
int parsedCommandLength = 0;
char** parsedCommand = parseLine(parsedArguments[0], &parsedCommandLength);
parsedArguments[numberOfArgs - 1] = deleteSpaces(parsedArguments[numberOfArgs - 1]);
if (fork() == 0) {
if (fd = open(parsedArguments[numberOfArgs - 1], O_WRONLY | O_CREAT |O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) < 0) {
perror("lsh");
return 1;
}
if (dup2(fd, 2) < 0) {
perror("lsh") ;
return 1;
}
close(fd);
execvp(parsedCommand[0], parsedCommand);
exit(0);
}
close(fd);
wait(NULL);
return 0;
}
parsedArguments are arguments splitted by 2>, then I take the last one as it is name of my file, and I process the previous one by splitting them on spaces (and they are in parsedCommand). For some reason the stderr prints on screen, it creates a file if it didn't exist but it is always empty. I don't know what might be the problem here.
A common error:
if (fd = open(...) < 0)
is equivalent to
if (fd = (open(...) < 0))
which is not what you want. You need:
if ( (fd = open(...)) < 0)
When open succeeds, open(...) < 0 evaluates to false and fd = open(...) < 0 assigns 0 to fd. The value returned by open, however, is lost.

Copying file fails, EBADF on closing output file descriptor

So I was following a little outdated book (2010) and I'm trying to copy a file with Linux system calls. This is what i have:
NOTE: Ignore the tlpi_hdr.h and error_functions.h, they define errExit() and fatal() and some otheres, they just print the error and exit.
#include <stdio.h>
#include <fcntl.h>
#include "lib/tlpi_hdr.h"
#include "lib/error_functions.h"
#ifndef BUF_SIZE
#define BUF_SIZE 1024
#endif
int main(int argc, char *argv[])
{
int inputFd, outputFd, openFlags;
mode_t filePerms;
ssize_t numRead;
char buf[BUF_SIZE];
if (argc != 3 || strcmp(argv[1], "--help") == 0) {
usageErr("%s old-file new-file\n", argv[0]);
}
inputFd = open(argv[1], O_RDONLY);
if (inputFd == -1) {
errExit("Opening file %s", argv[1]);
}
openFlags = O_CREAT | O_WRONLY | O_TRUNC;
filePerms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
outputFd = open(argv[2], openFlags, filePerms);
if (outputFd == -1) {
errExit("Opening file for writing %s", argv[1]);
}
while ((numRead = read(inputFd, buf, BUF_SIZE)) > 0) {
if (write(outputFd, buf, numRead) != numRead))
fatal("I/O Error");
if (numRead == -1)
fatal("Reading error");
}
if (close(outputFd == -1))
errExit("close input");
if (close(inputFd == -1))
errExit("close output");
return EXIT_SUCCESS;
}
I'm failing on closing of the output file descriptor with EBADF Bad file descriptor:
thinkpad :: ~/.tlpi % ./cp.o a b
ERROR [EBADF Bad file descriptor] close output
The file copies fine tho:
thinkpad :: ~/.tlpi % sha1sum a
40a925a93e149ac53d2630cde8adeb63b8134b29 a
thinkpad :: ~/.tlpi % sha1sum b
40a925a93e149ac53d2630cde8adeb63b8134b29 b
thinkpad :: ~/.tlpi %
Why?
Let's take a closer look at your close call:
close(outputFd == -1)
Here you are comparing outputFd to the value -1. The result of that is a boolean value, which in C will be either 0 or 1. This happens to be either standard input or standard output, depending on the result. Not a file you descriptor you should close.
My guess is that you meant
if (close(outputFd) == -1)

Open() for output not creating file

I have this function that utilizes open to set i/o redirection:
void setOutput(char * buffer){
int file = open(buffer, O_WRONLY || O_CREAT, S_IWUSR);
if(file < 0){ printf("error opening %s for output\n", buffer); }
if(dup2(file, 1) < 0){ printf("error with dup2 opening %s for output\n", buffer); }
}
When I run it, it works fine for files that are already defined but returns -1 when it receives a non-created file. Not sure why
You need to change the following
int file = open(buffer, O_WRONLY || O_CREAT, S_IWUSR);
To
int file = open(buffer, O_WRONLY | O_CREAT, S_IWUSR);
Format :
int open( char *filename, int access, int permission );
access : Should be provided as a bit wise OR operator, that means using | not || which is logical OR

c open() Undefined error: 0 on os x

On a mac running 10.8 i am trying to open a serial port.
ls /dev/cu* returns:
/dev/cu.Bluetooth-Modem /dev/cu.Bluetooth-PDA-Sync /dev/cu.usbserial-A1009TT7
i can see the port is there but when i try to open it i get Undefined error: 0(0). This is my code i use to open the port.
char *path = "/dev/cu.usbserial-A1009TT7";
open(path , O_RDWR | O_NOCTTY | O_NONBLOCK); // open the port
if (file == -1) {
printf("Error opening port : %s(%d).\n", strerror(errno), errno);
close(file);
return -1;
}
anyone have any idea why the port wont open?
thanks in advance.
Whoops! You meant to type this:
file = open(path , O_RDWR | O_NOCTTY | O_NONBLOCK);
^^^^^^^
Also, there is no need to close a file descriptor that isn't open.
if (file == -1) {
printf(...);
// close(file); Completely unnecessary. It's not valid!
return -1;
}

Resources