LinuxQuestions.org
Help answer threads with 0 replies.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Software
User Name
Password
Linux - Software This forum is for Software issues.
Having a problem installing a new program? Want to know which application is best for the job? Post your question in this forum.

Notices


Reply
  Search this Thread
Old 07-28-2011, 09:55 AM   #1
barunparichha
Member
 
Registered: Jun 2006
Location: Bangalore,india
Distribution: Linux(Redhat,fedora,suse,ubantu), Solaris (s8/s9/s10/nevada/open-solaris)
Posts: 293

Rep: Reputation: 32
dup2() with multiple execl() calls :


Code:
#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main()
{
        int fd;

        fd = open("del.txt",O_WRONLY | O_CREAT | O_TRUNC, 0644);
        dup2(fd,1);
        execl("/usr/bin/ls","ls",(char *)NULL);
        execl("/usr/bin/ls","ls","-l",(char *)NULL);
        close(fd);

}
Code:
 execl("/usr/bin/ls","ls",(char *)NULL);
        write(1,"I Love India\n",30);
I am getting output for first execl() call in my file "del.txt", the subsequent execl() or any redirection to STDOUT are not logged.




Is this a bug or issue with my programme ?

Thanks,
Barun Parichha
 
Old 07-28-2011, 04:53 PM   #2
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948
Quote:
Originally Posted by barunparichha View Post
I am getting output for first execl() call in my file "del.txt", the subsequent execl() or any redirection to STDOUT are not logged.
Of course not. If you read the man execl man page, you'd noticed the first sentence: The exec() family of functions replaces the current process image with a new process image.

If execl() (or any of the other exec family functions) succeed, the named executable will replace the current process. Your program will end there. (It will not exit, because it does not exit; it is just replaced by the new executable. The new executable gets the same process ID, and even gets to keep all the file descriptors opened by the previous process, unless explicitly marked close-on-exec. So the new executable is like a continuation of your program.)

To do what I suspect you want to do, you'll need to use fork() to create child processes (to run the external commands), and wait (or waitpid or waitid) to wait for the child process to exit before running the second command, or outputting to the descriptor yourself.

Last edited by Nominal Animal; 07-28-2011 at 04:55 PM.
 
Old 07-29-2011, 01:50 AM   #3
barunparichha
Member
 
Registered: Jun 2006
Location: Bangalore,india
Distribution: Linux(Redhat,fedora,suse,ubantu), Solaris (s8/s9/s10/nevada/open-solaris)
Posts: 293

Original Poster
Rep: Reputation: 32
Code:
#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main()
{
        int fd;

        fd = open("del.txt",O_WRONLY | O_CREAT | O_TRUNC, 0644);
        if(fork() == 0)
        {
                dup2(fd,1);
                execl("/usr/bin/ls","ls",(char *)NULL);
                close(fd);
        }
        else
        {
                wait(0);
                if(fork()==0)
                {
                        dup2(fd,1);
                        execl("/usr/bin/ls","ls","-l",(char *)NULL);
                        close(fd);
                }
        }
        close(fd);

}
This code is working.
 
Old 07-29-2011, 03:25 AM   #4
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948
Quote:
Originally Posted by barunparichha View Post
This code is working.
Right, it is very close to what I had in mind, too. Looks good!

I do have a couple of remarks. Nothing severe, or really important, but something you probably should be aware of:
  • You do not wait for the second command to exit, before the main program exits.
    You might wish to add another wait before exiting the program.
    You will see the difference if you add some code at the end of main() to write something to the open descriptor.
  • It would be better to have a return 127; or exit(127); instead of close(fd); after those execl(..); calls.
    This is because the code is only run if the execl() fails. As it stands, your code will close the descriptor, then fall through, continuing executing code after the if clauses. In this specific case, you'll just attempt to close the same descriptor again, which will just return -1 with errno set to EBADF, so nothing fatal there.
    Remember, that code is running in the child process, so it really should exit immediately if it cannot do the job it was assigned to do.
    Sometimes it is hard to notice which code is run if/when fall through happens, and you may end up executing code in the child process you only intended to be run in the parent. Using an explicit return or exit makes sure that does not happen. Using a code like 127 lets you detect if that happens, because 127 is a rare code; unlikely to be reported by any other program. (Code 0 is reserved for success, and 1 to 127 are all errors and guaranteed to be passed on as-is. Other codes may be mapped down to that range, or not, depending on the OS.)
  • You have omitted all error checking.
    open(), fork(), dup2(), execl(), and even close() may all fail. They all will return -1 (cast to their return type), and set errno to reflect the cause of the error.
    Just because the errors are rare, does not mean you should not handle them gracefully!
    Perhaps the most important would be to check fd (open() result). Perhaps the most overlooked error check in general is with close(). If the file resides on a shared filesystem, certain errors -- for example, running just a bit out of disk space -- are only reported when the file is closed. close() may thus return whatever errors in errno write() can. Most programmers seem to overlook that.

Good luck with your endeavours,
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

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
How to make Multiple calls using PJISP ? kumarkmmca Programming 1 04-13-2011 06:42 AM
how can make multiple calls of ip_append_data? othe Programming 1 07-13-2009 06:50 AM
Questions on efficiency of multiple fork() calls (in C) POW R TOC H Programming 8 07-21-2008 07:22 AM
Sockets: multiple send() calls throttle server framerate. JCipriani Programming 3 09-22-2005 08:06 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Software

All times are GMT -5. The time now is 07:15 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
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration