LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 10-20-2005, 11:12 AM   #1
lowpro2k3
Member
 
Registered: Oct 2003
Location: Canada
Distribution: Slackware
Posts: 340

Rep: Reputation: 30
Does duplicating a file descriptor in C allow you to write to both at once?


The application I'm working on needs a 'log to file' function, but data still needs to be sent to STDOUT_FILENO. Can I dup() the STDOUT_FILENO and write output to the file and stdout at the same time? Is this the purpose of duplicating a file descriptor?
 
Old 10-20-2005, 11:44 AM   #2
jim mcnamara
Member
 
Registered: May 2002
Posts: 964

Rep: Reputation: 36
Yes it does. But you cannot guarantee the order in which the data will actually appear in the file.

Instead of fiddling around in C, try tee as part of the script to run the file:

Code:
myfile | tee -a mylogfile
 
Old 10-20-2005, 11:48 AM   #3
itsme86
Senior Member
 
Registered: Jan 2004
Location: Oregon, USA
Distribution: Slackware
Posts: 1,246

Rep: Reputation: 59
The "split" happens in the reverse direction. Instead of having one file descriptor that points to two places it makes it so you have two file descriptors that point to one place.
 
Old 10-20-2005, 12:10 PM   #4
lowpro2k3
Member
 
Registered: Oct 2003
Location: Canada
Distribution: Slackware
Posts: 340

Original Poster
Rep: Reputation: 30
Quote:
Originally posted by itsme86
The "split" happens in the reverse direction. Instead of having one file descriptor that points to two places it makes it so you have two file descriptors that point to one place.
Hmm, it seems like you're right. Thats what I thought, but wasn't sure.

From dup(2):

Code:
SYNOPSIS
       #include <unistd.h>

       int dup(int oldfd);
       int dup2(int oldfd, int newfd);

DESCRIPTION
       dup and dup2 create a copy of the file descriptor oldfd.

       After  successful  return  of dup or dup2, the old and new descriptors may be used interchangeably. They
       share locks, file position pointers and flags; for example, if the file position is  modified  by  using
       lseek on one of the descriptors, the position is also changed for the other.

       The two descriptors do not share the close-on-exec flag, however.

       dup uses the lowest-numbered unused descriptor for the new descriptor.

       dup2 makes newfd be the copy of oldfd, closing newfd first if necessary.
I wrote this code to test what I had previously thought about dup2...Basically what it tries/tried to do was read a filename argument, open that file, and try to write data to stdout AND the file. It didn't work

I *can* interchange using STDOUT_FILENO and the new fd, the way you mentioned. This is what I thought dup and dup2 did, this kind of proved it...

Code:
/* test writing to multiple file descriptors at once */
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>

#define FILE_FLAGS O_CREAT|O_WRONLY|O_APPEND
#define FILE_MODE S_IWRITE|S_IREAD

int main(int argc, char* argv[])
{
 char buf[80];
 ssize_t bytes_read;
 int fd;

 if(argc != 2)
 {
  fprintf(stderr, "usage: ./dup-test <filename>\n");
  exit(1);
 }

 if((fd = open(argv[1], FILE_FLAGS, FILE_MODE)) == -1) 
 {
  perror("dup-test: error opening file");
  exit(1);
 }

 if(dup2(STDOUT_FILENO, fd) == -1)
 {
  perror("dup-test: error duplicating file descriptor");
  exit(1);
 }

 while((bytes_read = read(STDIN_FILENO, buf, 80)) != 0)
 {
  if(bytes_read < 0)
  {
   perror("dup-test: error reading data");
   exit(1);
  }

  if(write(STDOUT_FILENO, buf, bytes_read) < 0)
  {
   perror("dup-test: error writing data");
   exit(1);
  }
 }

 return 0;
}
So is there any way to cleanly do what I'm attempting? I want to write something in my code that looks like this:

Code:
/* setup program for logging all output to output file 
   AND stdout at the same time */
int main(int argc, char * argv[])
{
    /* process options... */
    switch(option) {
        /* set up program logging and continue on as normal */
        case 'l':
            logoutput(output_log);
            break;
        /* run the rest of the program */
    }

    /* run the rest of the program */
}
Sending output to tee isn't the best idea for this program, because output will come from all over the place, so I'd have to test if we're logging output every time I write to stdout (which happens alot). Also, output to a file is optional, its far from the default behaviour.

I'm kind of stumped on a clean way to handle this problem.

Last edited by lowpro2k3; 10-20-2005 at 12:15 PM.
 
Old 10-20-2005, 12:20 PM   #5
ioerror
Member
 
Registered: Sep 2005
Location: Old Blighty
Distribution: Slackware, NetBSD
Posts: 536

Rep: Reputation: 34
Code:
I wrote this code to test what I had previously thought about dup2...Basically what it tries/tried to do was read a filename argument, open that file, and try to write data to stdout AND the file. It didn't work :(
Doesn't work like that. You just closed stdout (the terminal) and redirected it to the file. A file descriptor can't refer to two files at once.

You can't do it directly. You'll have to write to both stdout and the file fd.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Get the absolute path of file using file descriptor. appas Programming 7 01-19-2012 11:47 AM
Hard disk failing? write error: Bad file descriptor glt Linux - Hardware 4 12-14-2005 10:41 AM
File Descriptor Limit rbd Linux - General 3 10-11-2004 01:57 PM
apt-file returns nothing; 'bad file descriptor' overbored Debian 3 10-03-2004 09:13 PM
File descriptor lido Linux - Newbie 5 07-17-2003 11:58 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 04:49 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration