detach

Git mirror of http://inglorion.net/software/detach/
git clone git://git.finwo.net/app/detach
Log | Files | Refs | LICENSE

detach.c (1581B)


      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <sys/types.h>
      4 #include <unistd.h>
      5 #include <fcntl.h>
      6 #include <string.h>
      7 
      8 #ifndef NULL
      9 #define NULL  ((void*) 0)
     10 #endif
     11 
     12 static void replacefd(int fd, const char *filename, int flags, int mode) {
     13 	int n;
     14 	n = open(filename, flags, mode);
     15 	if(n < 0) {
     16 		perror(filename);
     17 		exit(1);
     18 	} else {
     19 		dup2(n, fd);
     20 		close(n);
     21 	}
     22 }
     23 
     24 int main(int argc, char **argv) {
     25 	int do_fork = 1, command_start, i;
     26 	char *infile = NULL, *outfile = NULL, *errfile = NULL, *pidfile = NULL;
     27 	FILE *pidfh;
     28 
     29 	/* Parse command line */
     30 	for(i = 1; i < argc; i++) {
     31 		if(!strcmp(argv[i], "-e")) errfile = argv[++i];
     32 		else if(!strcmp(argv[i], "-f")) do_fork = 0;
     33 		else if(!strcmp(argv[i], "-i")) infile = argv[++i];
     34 		else if(!strcmp(argv[i], "-o")) outfile = argv[++i];
     35 		else if(!strcmp(argv[i], "-p")) pidfile = argv[++i];
     36 		else if(!strcmp(argv[i], "--")) {
     37 			i++;
     38 			break;
     39 		} else if(argv[i][0] == '-') {
     40 			fprintf(stderr, "Invalid option: %s\n", argv[i]);
     41 			exit(0x80);
     42 		} else break;
     43 	}
     44 	command_start = i;
     45 
     46 	if(do_fork && fork()) return 0;
     47 
     48 	if(pidfile) {
     49 		pidfh = fopen(pidfile, "w");
     50 		if(!pidfh) {
     51 			perror(pidfile);
     52 			exit(1);
     53 		}
     54 		fprintf(pidfh, "%d\n", getpid());
     55 		fclose(pidfh);
     56 	}
     57 
     58 	if(infile) replacefd(0, infile, O_RDONLY, 0666);
     59 	else close(0);
     60 	if(outfile) replacefd(1, outfile, O_WRONLY | O_CREAT | O_TRUNC, 0666);
     61 	else close(1);
     62 	if(errfile) replacefd(2, errfile, O_WRONLY | O_CREAT | O_TRUNC, 0666);
     63 	else close(2);
     64 	setsid();
     65 
     66 	execvp(argv[command_start], &argv[command_start]);
     67 
     68 	perror(argv[command_start]);
     69 	return -1;
     70 }