Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 16 Apr 1998 09:46:29 -0500 (CDT)
From:      Peter da Silva <peter@baileynm.com>
To:        FreeBSD-gnats-submit@FreeBSD.ORG
Subject:   misc/6320: detach - nohup on steroids
Message-ID:  <199804161446.JAA12754@pobox.nmti.com>

next in thread | raw e-mail | index | archive | help

>Number:         6320
>Category:       misc
>Synopsis:       Sometimes nohup isn't good enough.
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:
>Keywords:
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Thu Apr 16 07:50:00 PDT 1998
>Last-Modified:
>Originator:     Peter da Silva
>Organization:
Bailey Network Management
>Release:        FreeBSD 2.2.5-RELEASE i386
>Environment:

Any situation where you're kicking off a program to run as a daemon and
the induhvidual who wrote it decided that they really needed to trap
signals you've already set to be ignored.

>Description:

Normally programs that are going to run as a daemon double-fork themselves
to shed their parent, and setsid() to create a new process. Nohup doesn't
do this for you, so your nohupped process is still interacting with your
terminal.

>How-To-Repeat:

nohup intransigent-program &
logout
Watch it die screaming.

>Fix:
	
Detach completes the setsid/doublefork idiom for starting a daemon off.

# This is a shell archive.  Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file".  Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
#	Makefile
#	detach.1
#	detach.c
#
echo x - Makefile
sed 's/^X//' >Makefile << 'END-of-Makefile'
X# standard defines
XSHELL=/bin/sh
XCFLAGS=-O
XSHARFILES=Makefile $(MISC) $(CFILES)
XSHAR=$(TARGET).shar
X
X# program dependent defines
XOFILES=detach.o
XCFILES=detach.c
XTARGET=detach
XMISC=detach.1
X
Xdefault: $(TARGET)
X
Xall: $(TARGET) shar
X
Xshar: $(SHAR)
X
X$(TARGET): $(OFILES)
X	$(CC) $(CFLAGS) $(OFILES) -o $(TARGET)
X
X$(SHAR): $(SHARFILES)
X	shar >$(SHAR) $(SHARFILES)
END-of-Makefile
echo x - detach.1
sed 's/^X//' >detach.1 << 'END-of-detach.1'
X.TH DETACH 1
X.SH NAME
Xdetach \- when it absolutely has to run!
X.SH SYNOPSIS
X.B detach
X[-va] [ -f
X.I filename
X]
X.I command
X[
X.I args
X]
X.SH DESCRIPTION
X.B detach.
Xruns a command in a whole new
Xprocess group. Once you have detached a process, you can airmail
Xyour terminal to Brazil. It won't care.
X.SH OPTIONS
X.IP -v
XNatter at you about the command it's running, both on the terminal and in the
Xlog file.
X.IP "-f \fIfilename\fR"
XBy default, detach redirects output to "detach.out". You can
Xoverride this with the '-f' option. Really important if you
Xdon't have write access in the current directory.
X.IP -a
XAppend to the logfile instead of overwriting it.
X.SH AUTHOR
XPeter da Silva
X.SH NOTES
X.B Detach
Xuses
X.B execvp 
Xto execute the command. If you want to detach multiple commands
Xuse \fBdetach \fIoptions\fB sh -c\fR '\fIcommand\fR'...
END-of-detach.1
echo x - detach.c
sed 's/^X//' >detach.c << 'END-of-detach.c'
X#include <stdio.h>
X#include <fcntl.h>
X
Xmain(ac, av)
Xint ac;
Xchar **av;
X{
X	int pid;
X	char *file;
X	int vflag;
X	int mode;
X
X	close(0); open("/dev/null", 0);
X	close(1);
X
X	file = "detach.out";
X	mode = O_TRUNC;
X	vflag = 0;
X
X	while(**++av == '-') {
X		while(*++*av) {
X			switch(**av) {
X				case 'f':
X					if(*++*av)
X						file = *av;
X					else
X						file = *++av;
X					goto next_arg;
X				case 'v':
X					vflag++;
X					break;
X				case 'a':
X					mode = O_APPEND;
X					break;
X			}
X		}
Xnext_arg:	;
X	}
X
X	if(open(file, O_WRONLY|mode|O_CREAT, 0666) < 0) {
X		perror(file);
X		exit(1);
X	}
X
X	switch(pid = fork()) {
X		case -1:
X			perror(av[0]);
X			exit(1);
X			break;
X		case 0:
X			if(vflag) {
X				char **p = av;
X
X				printf("# %d", getpid());
X				while(*p)
X					printf(" %s", *p++);
X				putchar('\n');
X			}
X			fflush(stdout);
X			close(2); dup(1);
X			setsid();
X			execv(av[0], av);
X			execvp(av[0], av);
X			perror(av[0]);
X			exit(1);
X			break;
X		default:
X			if(vflag) {
X				fprintf(stderr, "# %d", pid);
X				while(*av)
X					fprintf(stderr, " %s", *av++);
X				fputc('\n', stderr);
X			} else
X				fprintf(stderr, "%d\n", pid);
X			break;
X	}
X}
END-of-detach.c
exit

>Audit-Trail:
>Unformatted:

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199804161446.JAA12754>