/* $Id: dlnohup.c 34 2007-09-19 12:54:18Z dleigh $ * * dlnohup.c - nohup replacement with control over stdin, stdout, stderr * * Usage: dlnohup [ ...] * * - The files for the 3 streams are required (use /dev/null if you want to * ignore that stream). * * - Files for stdout and stderr output will be created if they do not exist * (the program will abort if the stdin file does not exist). * * - If they do exist, the output files will be appended to, not truncated; * note that this may CORRUPT files mounted over NFS if multiple programs * are appending to the same file. ----- Copyright (c) 2006 Dylan Leigh. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Modified versions must be plainly marked as such, and must not be misrepresented as being the original software. 4. The names of the authors or copyright holders must not be used to endorse or promote products derived from this software without prior written permission. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----- */ #include #include #include #include #include #include int main(int argc, char **argv) { int infd, outfd, errfd; //check usage if (argc < 5) { fprintf(stderr, "Usage: %s [...]\n", argv[0]); return EXIT_FAILURE; /* Note: return is used when no special cleanup is desired. exit() * should close open files according to ANSI C; returningfrom main() * makes no such guarantee. */ } //disconnect sighup if (signal(SIGHUP, SIG_IGN) == SIG_ERR) { fprintf(stderr, "%s: signal() error\n", argv[0]); exit(EXIT_FAILURE); } //open files infd = open(argv[1], O_RDONLY); if (infd == -1) { perror(argv[1]); exit(EXIT_FAILURE); } outfd = open(argv[2], O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR | S_IRGRP); if (outfd == -1) { perror(argv[2]); exit(EXIT_FAILURE); } errfd = open(argv[3], O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR | S_IRGRP); if (errfd == -1) { perror(argv[3]); exit(EXIT_FAILURE); } //connect files if (dup2(infd, STDIN_FILENO) == -1) { perror(argv[0]); exit(EXIT_FAILURE); } if (dup2(outfd, STDOUT_FILENO) == -1) { perror(argv[0]); exit(EXIT_FAILURE); } if (dup2(errfd, STDERR_FILENO) == -1) { perror(argv[0]); exit(EXIT_FAILURE); } close(infd); close(outfd); close(errfd); //exec execvp(argv[4], &argv[4]); //on error print to stderr TODO print to original stderr? fprintf(stderr, "%s: execvp error: ", argv[0]); perror(NULL); exit(EXIT_FAILURE); return EXIT_FAILURE; }