mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-27 05:13:10 +00:00
Remove fishd.cpp source, docs, and target from Makefile and Xcode
project
This commit is contained in:
parent
741342ba1d
commit
be3e64e5ea
5 changed files with 1 additions and 1232 deletions
20
Makefile.in
20
Makefile.in
|
@ -111,14 +111,6 @@ BUILTIN_FILES := builtin_set.cpp builtin_commandline.cpp \
|
||||||
FISH_TESTS_OBJS := $(FISH_OBJS) fish_tests.o
|
FISH_TESTS_OBJS := $(FISH_OBJS) fish_tests.o
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# All objects that the system needs to build fishd
|
|
||||||
#
|
|
||||||
|
|
||||||
FISHD_OBJS := fishd.o env_universal_common.o wutil.o print_help.o \
|
|
||||||
common.o utf8.o fish_version.o
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# All objects needed to build mimedb
|
# All objects needed to build mimedb
|
||||||
#
|
#
|
||||||
|
@ -181,7 +173,7 @@ FUNCTIONS_DIR_FILES := $(wildcard share/functions/*.fish)
|
||||||
# Programs to install
|
# Programs to install
|
||||||
#
|
#
|
||||||
|
|
||||||
PROGRAMS := fish mimedb fishd fish_indent
|
PROGRAMS := fish mimedb fish_indent
|
||||||
|
|
||||||
#
|
#
|
||||||
# Manual pages to install
|
# Manual pages to install
|
||||||
|
@ -688,14 +680,6 @@ fish: $(FISH_OBJS) fish.o
|
||||||
$(CXX) $(CXXFLAGS) $(LDFLAGS_FISH) $(FISH_OBJS) fish.o $(LIBS) -o $@
|
$(CXX) $(CXXFLAGS) $(LDFLAGS_FISH) $(FISH_OBJS) fish.o $(LIBS) -o $@
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# Build the fishd program.
|
|
||||||
#
|
|
||||||
|
|
||||||
fishd: $(FISHD_OBJS)
|
|
||||||
$(CXX) $(CXXFLAGS) $(LDFLAGS) $(FISHD_OBJS) $(LIBS) -o $@
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Build the fish_tests program.
|
# Build the fish_tests program.
|
||||||
#
|
#
|
||||||
|
@ -842,8 +826,6 @@ fish.o: highlight.h env.h color.h builtin.h function.h event.h wutil.h
|
||||||
fish.o: sanity.h proc.h parse_tree.h tokenizer.h parse_constants.h parser.h
|
fish.o: sanity.h proc.h parse_tree.h tokenizer.h parse_constants.h parser.h
|
||||||
fish.o: expand.h intern.h exec.h output.h screen.h history.h path.h input.h
|
fish.o: expand.h intern.h exec.h output.h screen.h history.h path.h input.h
|
||||||
fish.o: input_common.h fish_version.h
|
fish.o: input_common.h fish_version.h
|
||||||
fishd.o: config.h signal.h fallback.h util.h common.h wutil.h
|
|
||||||
fishd.o: env_universal_common.h env.h path.h print_help.h fish_version.h
|
|
||||||
fish_indent.o: config.h fallback.h signal.h util.h common.h wutil.h
|
fish_indent.o: config.h fallback.h signal.h util.h common.h wutil.h
|
||||||
fish_indent.o: tokenizer.h print_help.h parser_keywords.h fish_version.h
|
fish_indent.o: tokenizer.h print_help.h parser_keywords.h fish_version.h
|
||||||
fish_tests.o: config.h signal.h fallback.h util.h common.h proc.h io.h
|
fish_tests.o: config.h signal.h fallback.h util.h common.h proc.h io.h
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
\section fishd fishd - universal variable daemon
|
|
||||||
|
|
||||||
\subsection fishd-synopsis Synopsis
|
|
||||||
<tt>fishd [(-h|--help|-v|--version)]</tt>
|
|
||||||
|
|
||||||
\subsection fishd-description Description
|
|
||||||
|
|
||||||
The \c fishd daemon is used to load, save and distribute universal
|
|
||||||
variable information. \c fish automatically connects to \c fishd via a socket
|
|
||||||
on startup.
|
|
||||||
|
|
||||||
\c fishd is started and stopped automatically.
|
|
||||||
|
|
||||||
The following options are available if starting \c fishd manually:
|
|
||||||
|
|
||||||
- <tt>-h</tt> or <tt>--help</tt> displays this help message and then exits
|
|
||||||
- <tt>-v</tt> or <tt>--version</tt> displays the current fish version and then exits
|
|
||||||
|
|
||||||
\subsection fishd-files Files
|
|
||||||
|
|
||||||
- \c ~/.config/fish/fishd.MACHINE_ID - permanent storage location for universal
|
|
||||||
variable data. \c MACHINE_ID is generally based on the machine's MAC address.
|
|
||||||
|
|
||||||
The data is stored as a set of \c set and \c set_export commands such as
|
|
||||||
would be parsed by fishd. The file must always be stored in YAML format.
|
|
||||||
If an instance of fishd is running (which is generally the case), manual
|
|
||||||
modifications to \c ~/.fishd.MACHINE_ID will be lost. Do NOT edit this file manually!
|
|
||||||
|
|
||||||
- \c /tmp/fishd.socket.USERNAME - the socket which fishd uses to communicate
|
|
||||||
with all clients.
|
|
||||||
|
|
||||||
- /tmp/fishd.log.USERNAME - the fishd log file
|
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
);
|
);
|
||||||
dependencies = (
|
dependencies = (
|
||||||
D07D265715E33B86009E43F6 /* PBXTargetDependency */,
|
D07D265715E33B86009E43F6 /* PBXTargetDependency */,
|
||||||
D07D265915E33B86009E43F6 /* PBXTargetDependency */,
|
|
||||||
D07D265D15E33B86009E43F6 /* PBXTargetDependency */,
|
D07D265D15E33B86009E43F6 /* PBXTargetDependency */,
|
||||||
D0A56500168D257900AF6161 /* PBXTargetDependency */,
|
D0A56500168D257900AF6161 /* PBXTargetDependency */,
|
||||||
);
|
);
|
||||||
|
@ -47,7 +46,6 @@
|
||||||
);
|
);
|
||||||
dependencies = (
|
dependencies = (
|
||||||
D0F01A1315AA36280034B3B1 /* PBXTargetDependency */,
|
D0F01A1315AA36280034B3B1 /* PBXTargetDependency */,
|
||||||
D0F01A1515AA362E0034B3B1 /* PBXTargetDependency */,
|
|
||||||
D0F01A1715AA36300034B3B1 /* PBXTargetDependency */,
|
D0F01A1715AA36300034B3B1 /* PBXTargetDependency */,
|
||||||
D0A564EF168D09C000AF6161 /* PBXTargetDependency */,
|
D0A564EF168D09C000AF6161 /* PBXTargetDependency */,
|
||||||
);
|
);
|
||||||
|
@ -59,7 +57,6 @@
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
D00F63F119137E9D00FCCDEC /* fish_version.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D00F63F019137E9D00FCCDEC /* fish_version.cpp */; };
|
D00F63F119137E9D00FCCDEC /* fish_version.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D00F63F019137E9D00FCCDEC /* fish_version.cpp */; };
|
||||||
D00F63F219137E9D00FCCDEC /* fish_version.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D00F63F019137E9D00FCCDEC /* fish_version.cpp */; };
|
D00F63F219137E9D00FCCDEC /* fish_version.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D00F63F019137E9D00FCCDEC /* fish_version.cpp */; };
|
||||||
D00F63F31914C5F800FCCDEC /* fish_version.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D00F63F019137E9D00FCCDEC /* fish_version.cpp */; };
|
|
||||||
D01A2D24169B736200767098 /* man1 in Copy Files */ = {isa = PBXBuildFile; fileRef = D01A2D23169B730A00767098 /* man1 */; };
|
D01A2D24169B736200767098 /* man1 in Copy Files */ = {isa = PBXBuildFile; fileRef = D01A2D23169B730A00767098 /* man1 */; };
|
||||||
D01A2D25169B737700767098 /* man1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = D01A2D23169B730A00767098 /* man1 */; };
|
D01A2D25169B737700767098 /* man1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = D01A2D23169B730A00767098 /* man1 */; };
|
||||||
D031890C15E36E4600D9CC39 /* base in Resources */ = {isa = PBXBuildFile; fileRef = D031890915E36D9800D9CC39 /* base */; };
|
D031890C15E36E4600D9CC39 /* base in Resources */ = {isa = PBXBuildFile; fileRef = D031890915E36D9800D9CC39 /* base */; };
|
||||||
|
@ -120,7 +117,6 @@
|
||||||
D0A56501168D258300AF6161 /* man in Copy Files */ = {isa = PBXBuildFile; fileRef = D0A564F1168D0BAB00AF6161 /* man */; };
|
D0A56501168D258300AF6161 /* man in Copy Files */ = {isa = PBXBuildFile; fileRef = D0A564F1168D0BAB00AF6161 /* man */; };
|
||||||
D0C52F371765284C00BFAB82 /* parse_tree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0C52F351765284C00BFAB82 /* parse_tree.cpp */; };
|
D0C52F371765284C00BFAB82 /* parse_tree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0C52F351765284C00BFAB82 /* parse_tree.cpp */; };
|
||||||
D0C9733818DE5449002D7C81 /* utf8.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0C9733718DE5449002D7C81 /* utf8.cpp */; };
|
D0C9733818DE5449002D7C81 /* utf8.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0C9733718DE5449002D7C81 /* utf8.cpp */; };
|
||||||
D0C9733918DE5449002D7C81 /* utf8.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0C9733718DE5449002D7C81 /* utf8.cpp */; };
|
|
||||||
D0CBD587159EF0E10024809C /* launch_fish.scpt in Resources */ = {isa = PBXBuildFile; fileRef = D0CBD586159EF0E10024809C /* launch_fish.scpt */; };
|
D0CBD587159EF0E10024809C /* launch_fish.scpt in Resources */ = {isa = PBXBuildFile; fileRef = D0CBD586159EF0E10024809C /* launch_fish.scpt */; };
|
||||||
D0D02A67159837AD008E62BD /* complete.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0853713B3ACEE0099B651 /* complete.cpp */; };
|
D0D02A67159837AD008E62BD /* complete.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0853713B3ACEE0099B651 /* complete.cpp */; };
|
||||||
D0D02A69159837B2008E62BD /* env.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0853A13B3ACEE0099B651 /* env.cpp */; };
|
D0D02A69159837B2008E62BD /* env.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0853A13B3ACEE0099B651 /* env.cpp */; };
|
||||||
|
@ -158,12 +154,6 @@
|
||||||
D0D02A89159839DF008E62BD /* fish.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0854213B3ACEE0099B651 /* fish.cpp */; };
|
D0D02A89159839DF008E62BD /* fish.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0854213B3ACEE0099B651 /* fish.cpp */; };
|
||||||
D0D02A8D15983CFA008E62BD /* libncurses.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D0D02A8C15983CFA008E62BD /* libncurses.dylib */; };
|
D0D02A8D15983CFA008E62BD /* libncurses.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D0D02A8C15983CFA008E62BD /* libncurses.dylib */; };
|
||||||
D0D02A8F15983D8F008E62BD /* parser_keywords.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0855313B3ACEE0099B651 /* parser_keywords.cpp */; };
|
D0D02A8F15983D8F008E62BD /* parser_keywords.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0855313B3ACEE0099B651 /* parser_keywords.cpp */; };
|
||||||
D0D02AC215985F3F008E62BD /* fishd.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0854313B3ACEE0099B651 /* fishd.cpp */; };
|
|
||||||
D0D02AC315985F43008E62BD /* env_universal_common.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0853813B3ACEE0099B651 /* env_universal_common.cpp */; };
|
|
||||||
D0D02AC415985F4D008E62BD /* wutil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0856113B3ACEE0099B651 /* wutil.cpp */; };
|
|
||||||
D0D02AC515985F5B008E62BD /* print_help.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0855613B3ACEE0099B651 /* print_help.cpp */; };
|
|
||||||
D0D02AC615985F65008E62BD /* common.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0853613B3ACEE0099B651 /* common.cpp */; };
|
|
||||||
D0D02AC715985F9D008E62BD /* libncurses.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D0D02A8C15983CFA008E62BD /* libncurses.dylib */; };
|
|
||||||
D0D02AD615986492008E62BD /* fish_indent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0853F13B3ACEE0099B651 /* fish_indent.cpp */; };
|
D0D02AD615986492008E62BD /* fish_indent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0853F13B3ACEE0099B651 /* fish_indent.cpp */; };
|
||||||
D0D02AD715986498008E62BD /* print_help.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0855613B3ACEE0099B651 /* print_help.cpp */; };
|
D0D02AD715986498008E62BD /* print_help.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0855613B3ACEE0099B651 /* print_help.cpp */; };
|
||||||
D0D02AD81598649E008E62BD /* common.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0853613B3ACEE0099B651 /* common.cpp */; };
|
D0D02AD81598649E008E62BD /* common.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0853613B3ACEE0099B651 /* common.cpp */; };
|
||||||
|
@ -174,7 +164,6 @@
|
||||||
D0D2694915983772005D9B9C /* function.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0854413B3ACEE0099B651 /* function.cpp */; };
|
D0D2694915983772005D9B9C /* function.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0854413B3ACEE0099B651 /* function.cpp */; };
|
||||||
D0D2694A15983779005D9B9C /* builtin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0853513B3ACEE0099B651 /* builtin.cpp */; };
|
D0D2694A15983779005D9B9C /* builtin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0853513B3ACEE0099B651 /* builtin.cpp */; };
|
||||||
D0F019F115A977140034B3B1 /* fish in CopyFiles */ = {isa = PBXBuildFile; fileRef = D0D2693C159835CA005D9B9C /* fish */; };
|
D0F019F115A977140034B3B1 /* fish in CopyFiles */ = {isa = PBXBuildFile; fileRef = D0D2693C159835CA005D9B9C /* fish */; };
|
||||||
D0F019F215A977270034B3B1 /* fishd in CopyFiles */ = {isa = PBXBuildFile; fileRef = D0D02ABC15985EF9008E62BD /* fishd */; };
|
|
||||||
D0F019F315A977290034B3B1 /* fish_indent in CopyFiles */ = {isa = PBXBuildFile; fileRef = D0D02AD01598642A008E62BD /* fish_indent */; };
|
D0F019F315A977290034B3B1 /* fish_indent in CopyFiles */ = {isa = PBXBuildFile; fileRef = D0D02AD01598642A008E62BD /* fish_indent */; };
|
||||||
D0F019F815A977AB0034B3B1 /* config.fish in CopyFiles */ = {isa = PBXBuildFile; fileRef = D0CBD580159EE48F0024809C /* config.fish */; };
|
D0F019F815A977AB0034B3B1 /* config.fish in CopyFiles */ = {isa = PBXBuildFile; fileRef = D0CBD580159EE48F0024809C /* config.fish */; };
|
||||||
D0F019FD15A977CA0034B3B1 /* config.fish in CopyFiles */ = {isa = PBXBuildFile; fileRef = D0C4FD9415A7D7EE00212EF1 /* config.fish */; };
|
D0F019FD15A977CA0034B3B1 /* config.fish in CopyFiles */ = {isa = PBXBuildFile; fileRef = D0C4FD9415A7D7EE00212EF1 /* config.fish */; };
|
||||||
|
@ -198,13 +187,6 @@
|
||||||
remoteGlobalIDString = D0D2693B159835CA005D9B9C;
|
remoteGlobalIDString = D0D2693B159835CA005D9B9C;
|
||||||
remoteInfo = fish_shell;
|
remoteInfo = fish_shell;
|
||||||
};
|
};
|
||||||
D07D265A15E33B86009E43F6 /* PBXContainerItemProxy */ = {
|
|
||||||
isa = PBXContainerItemProxy;
|
|
||||||
containerPortal = D0A084F213B3AC130099B651 /* Project object */;
|
|
||||||
proxyType = 1;
|
|
||||||
remoteGlobalIDString = D0D02ABB15985EF9008E62BD;
|
|
||||||
remoteInfo = fishd;
|
|
||||||
};
|
|
||||||
D07D265E15E33B86009E43F6 /* PBXContainerItemProxy */ = {
|
D07D265E15E33B86009E43F6 /* PBXContainerItemProxy */ = {
|
||||||
isa = PBXContainerItemProxy;
|
isa = PBXContainerItemProxy;
|
||||||
containerPortal = D0A084F213B3AC130099B651 /* Project object */;
|
containerPortal = D0A084F213B3AC130099B651 /* Project object */;
|
||||||
|
@ -233,13 +215,6 @@
|
||||||
remoteGlobalIDString = D0D2693B159835CA005D9B9C;
|
remoteGlobalIDString = D0D2693B159835CA005D9B9C;
|
||||||
remoteInfo = fish_shell;
|
remoteInfo = fish_shell;
|
||||||
};
|
};
|
||||||
D0F01A1415AA362E0034B3B1 /* PBXContainerItemProxy */ = {
|
|
||||||
isa = PBXContainerItemProxy;
|
|
||||||
containerPortal = D0A084F213B3AC130099B651 /* Project object */;
|
|
||||||
proxyType = 1;
|
|
||||||
remoteGlobalIDString = D0D02ABB15985EF9008E62BD;
|
|
||||||
remoteInfo = fishd;
|
|
||||||
};
|
|
||||||
D0F01A1615AA36300034B3B1 /* PBXContainerItemProxy */ = {
|
D0F01A1615AA36300034B3B1 /* PBXContainerItemProxy */ = {
|
||||||
isa = PBXContainerItemProxy;
|
isa = PBXContainerItemProxy;
|
||||||
containerPortal = D0A084F213B3AC130099B651 /* Project object */;
|
containerPortal = D0A084F213B3AC130099B651 /* Project object */;
|
||||||
|
@ -325,7 +300,6 @@
|
||||||
dstSubfolderSpec = 1;
|
dstSubfolderSpec = 1;
|
||||||
files = (
|
files = (
|
||||||
D0F019F115A977140034B3B1 /* fish in CopyFiles */,
|
D0F019F115A977140034B3B1 /* fish in CopyFiles */,
|
||||||
D0F019F215A977270034B3B1 /* fishd in CopyFiles */,
|
|
||||||
D0F019F315A977290034B3B1 /* fish_indent in CopyFiles */,
|
D0F019F315A977290034B3B1 /* fish_indent in CopyFiles */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
@ -486,7 +460,6 @@
|
||||||
D0D02A8C15983CFA008E62BD /* libncurses.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libncurses.dylib; path = usr/lib/libncurses.dylib; sourceTree = SDKROOT; };
|
D0D02A8C15983CFA008E62BD /* libncurses.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libncurses.dylib; path = usr/lib/libncurses.dylib; sourceTree = SDKROOT; };
|
||||||
D0D02A9A15985A75008E62BD /* fish.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = fish.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
D0D02A9A15985A75008E62BD /* fish.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = fish.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
D0D02AA915985C0C008E62BD /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = osx/Info.plist; sourceTree = "<group>"; };
|
D0D02AA915985C0C008E62BD /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = osx/Info.plist; sourceTree = "<group>"; };
|
||||||
D0D02ABC15985EF9008E62BD /* fishd */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = fishd; sourceTree = BUILT_PRODUCTS_DIR; };
|
|
||||||
D0D02AD01598642A008E62BD /* fish_indent */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = fish_indent; sourceTree = BUILT_PRODUCTS_DIR; };
|
D0D02AD01598642A008E62BD /* fish_indent */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = fish_indent; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
D0D02AFA159871B2008E62BD /* osx_fish_launcher.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = osx_fish_launcher.m; path = osx/osx_fish_launcher.m; sourceTree = "<group>"; };
|
D0D02AFA159871B2008E62BD /* osx_fish_launcher.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = osx_fish_launcher.m; path = osx/osx_fish_launcher.m; sourceTree = "<group>"; };
|
||||||
D0D2693C159835CA005D9B9C /* fish */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = fish; sourceTree = BUILT_PRODUCTS_DIR; };
|
D0D2693C159835CA005D9B9C /* fish */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = fish; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
@ -506,14 +479,6 @@
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
D0D02AB915985EF9008E62BD /* Frameworks */ = {
|
|
||||||
isa = PBXFrameworksBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
D0D02AC715985F9D008E62BD /* libncurses.dylib in Frameworks */,
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
D0D02ACD1598642A008E62BD /* Frameworks */ = {
|
D0D02ACD1598642A008E62BD /* Frameworks */ = {
|
||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
|
@ -746,7 +711,6 @@
|
||||||
children = (
|
children = (
|
||||||
D0D2693C159835CA005D9B9C /* fish */,
|
D0D2693C159835CA005D9B9C /* fish */,
|
||||||
D0D02A9A15985A75008E62BD /* fish.app */,
|
D0D02A9A15985A75008E62BD /* fish.app */,
|
||||||
D0D02ABC15985EF9008E62BD /* fishd */,
|
|
||||||
D0D02AD01598642A008E62BD /* fish_indent */,
|
D0D02AD01598642A008E62BD /* fish_indent */,
|
||||||
D08A328D17B4455100F3A533 /* fish_tests */,
|
D08A328D17B4455100F3A533 /* fish_tests */,
|
||||||
);
|
);
|
||||||
|
@ -816,22 +780,6 @@
|
||||||
productReference = D0D02A9A15985A75008E62BD /* fish.app */;
|
productReference = D0D02A9A15985A75008E62BD /* fish.app */;
|
||||||
productType = "com.apple.product-type.application";
|
productType = "com.apple.product-type.application";
|
||||||
};
|
};
|
||||||
D0D02ABB15985EF9008E62BD /* fishd */ = {
|
|
||||||
isa = PBXNativeTarget;
|
|
||||||
buildConfigurationList = D0D02ABF15985EFA008E62BD /* Build configuration list for PBXNativeTarget "fishd" */;
|
|
||||||
buildPhases = (
|
|
||||||
D0D02AB815985EF9008E62BD /* Sources */,
|
|
||||||
D0D02AB915985EF9008E62BD /* Frameworks */,
|
|
||||||
);
|
|
||||||
buildRules = (
|
|
||||||
);
|
|
||||||
dependencies = (
|
|
||||||
);
|
|
||||||
name = fishd;
|
|
||||||
productName = fishd;
|
|
||||||
productReference = D0D02ABC15985EF9008E62BD /* fishd */;
|
|
||||||
productType = "com.apple.product-type.tool";
|
|
||||||
};
|
|
||||||
D0D02ACF1598642A008E62BD /* fish_indent */ = {
|
D0D02ACF1598642A008E62BD /* fish_indent */ = {
|
||||||
isa = PBXNativeTarget;
|
isa = PBXNativeTarget;
|
||||||
buildConfigurationList = D0D02AD31598642A008E62BD /* Build configuration list for PBXNativeTarget "fish_indent" */;
|
buildConfigurationList = D0D02AD31598642A008E62BD /* Build configuration list for PBXNativeTarget "fish_indent" */;
|
||||||
|
@ -888,7 +836,6 @@
|
||||||
D0F019EC15A976F30034B3B1 /* base */,
|
D0F019EC15A976F30034B3B1 /* base */,
|
||||||
D0D02A9915985A75008E62BD /* fish.app */,
|
D0D02A9915985A75008E62BD /* fish.app */,
|
||||||
D0D2693B159835CA005D9B9C /* fish_shell */,
|
D0D2693B159835CA005D9B9C /* fish_shell */,
|
||||||
D0D02ABB15985EF9008E62BD /* fishd */,
|
|
||||||
D0D02ACF1598642A008E62BD /* fish_indent */,
|
D0D02ACF1598642A008E62BD /* fish_indent */,
|
||||||
D08A328C17B4455100F3A533 /* fish_tests */,
|
D08A328C17B4455100F3A533 /* fish_tests */,
|
||||||
D0A564E6168CFDD800AF6161 /* man_pages */,
|
D0A564E6168CFDD800AF6161 /* man_pages */,
|
||||||
|
@ -1115,20 +1062,6 @@
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
D0D02AB815985EF9008E62BD /* Sources */ = {
|
|
||||||
isa = PBXSourcesBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
D00F63F31914C5F800FCCDEC /* fish_version.cpp in Sources */,
|
|
||||||
D0D02AC215985F3F008E62BD /* fishd.cpp in Sources */,
|
|
||||||
D0D02AC315985F43008E62BD /* env_universal_common.cpp in Sources */,
|
|
||||||
D0C9733918DE5449002D7C81 /* utf8.cpp in Sources */,
|
|
||||||
D0D02AC415985F4D008E62BD /* wutil.cpp in Sources */,
|
|
||||||
D0D02AC515985F5B008E62BD /* print_help.cpp in Sources */,
|
|
||||||
D0D02AC615985F65008E62BD /* common.cpp in Sources */,
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
D0D02ACC1598642A008E62BD /* Sources */ = {
|
D0D02ACC1598642A008E62BD /* Sources */ = {
|
||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
|
@ -1214,11 +1147,6 @@
|
||||||
target = D0D2693B159835CA005D9B9C /* fish_shell */;
|
target = D0D2693B159835CA005D9B9C /* fish_shell */;
|
||||||
targetProxy = D07D265815E33B86009E43F6 /* PBXContainerItemProxy */;
|
targetProxy = D07D265815E33B86009E43F6 /* PBXContainerItemProxy */;
|
||||||
};
|
};
|
||||||
D07D265915E33B86009E43F6 /* PBXTargetDependency */ = {
|
|
||||||
isa = PBXTargetDependency;
|
|
||||||
target = D0D02ABB15985EF9008E62BD /* fishd */;
|
|
||||||
targetProxy = D07D265A15E33B86009E43F6 /* PBXContainerItemProxy */;
|
|
||||||
};
|
|
||||||
D07D265D15E33B86009E43F6 /* PBXTargetDependency */ = {
|
D07D265D15E33B86009E43F6 /* PBXTargetDependency */ = {
|
||||||
isa = PBXTargetDependency;
|
isa = PBXTargetDependency;
|
||||||
target = D0D02ACF1598642A008E62BD /* fish_indent */;
|
target = D0D02ACF1598642A008E62BD /* fish_indent */;
|
||||||
|
@ -1239,11 +1167,6 @@
|
||||||
target = D0D2693B159835CA005D9B9C /* fish_shell */;
|
target = D0D2693B159835CA005D9B9C /* fish_shell */;
|
||||||
targetProxy = D0F01A1215AA36280034B3B1 /* PBXContainerItemProxy */;
|
targetProxy = D0F01A1215AA36280034B3B1 /* PBXContainerItemProxy */;
|
||||||
};
|
};
|
||||||
D0F01A1515AA362E0034B3B1 /* PBXTargetDependency */ = {
|
|
||||||
isa = PBXTargetDependency;
|
|
||||||
target = D0D02ABB15985EF9008E62BD /* fishd */;
|
|
||||||
targetProxy = D0F01A1415AA362E0034B3B1 /* PBXContainerItemProxy */;
|
|
||||||
};
|
|
||||||
D0F01A1715AA36300034B3B1 /* PBXTargetDependency */ = {
|
D0F01A1715AA36300034B3B1 /* PBXTargetDependency */ = {
|
||||||
isa = PBXTargetDependency;
|
isa = PBXTargetDependency;
|
||||||
target = D0D02ACF1598642A008E62BD /* fish_indent */;
|
target = D0D02ACF1598642A008E62BD /* fish_indent */;
|
||||||
|
@ -1328,18 +1251,6 @@
|
||||||
};
|
};
|
||||||
name = "Release_C++11";
|
name = "Release_C++11";
|
||||||
};
|
};
|
||||||
D007FDDF17136EAA00A52BE6 /* Release_C++11 */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
buildSettings = {
|
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
|
||||||
COPY_PHASE_STRIP = YES;
|
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
|
||||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
|
||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
||||||
};
|
|
||||||
name = "Release_C++11";
|
|
||||||
};
|
|
||||||
D007FDE017136EAA00A52BE6 /* Release_C++11 */ = {
|
D007FDE017136EAA00A52BE6 /* Release_C++11 */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
@ -1596,30 +1507,6 @@
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
};
|
};
|
||||||
D0D02AC015985EFA008E62BD /* Debug */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
buildSettings = {
|
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
|
||||||
COPY_PHASE_STRIP = NO;
|
|
||||||
GCC_DYNAMIC_NO_PIC = NO;
|
|
||||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
|
||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
||||||
};
|
|
||||||
name = Debug;
|
|
||||||
};
|
|
||||||
D0D02AC115985EFA008E62BD /* Release */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
buildSettings = {
|
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
|
||||||
COPY_PHASE_STRIP = YES;
|
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
|
||||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
|
||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
||||||
};
|
|
||||||
name = Release;
|
|
||||||
};
|
|
||||||
D0D02AD41598642A008E62BD /* Debug */ = {
|
D0D02AD41598642A008E62BD /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
@ -1755,16 +1642,6 @@
|
||||||
defaultConfigurationIsVisible = 0;
|
defaultConfigurationIsVisible = 0;
|
||||||
defaultConfigurationName = Release;
|
defaultConfigurationName = Release;
|
||||||
};
|
};
|
||||||
D0D02ABF15985EFA008E62BD /* Build configuration list for PBXNativeTarget "fishd" */ = {
|
|
||||||
isa = XCConfigurationList;
|
|
||||||
buildConfigurations = (
|
|
||||||
D0D02AC015985EFA008E62BD /* Debug */,
|
|
||||||
D0D02AC115985EFA008E62BD /* Release */,
|
|
||||||
D007FDDF17136EAA00A52BE6 /* Release_C++11 */,
|
|
||||||
);
|
|
||||||
defaultConfigurationIsVisible = 0;
|
|
||||||
defaultConfigurationName = Release;
|
|
||||||
};
|
|
||||||
D0D02AD31598642A008E62BD /* Build configuration list for PBXNativeTarget "fish_indent" */ = {
|
D0D02AD31598642A008E62BD /* Build configuration list for PBXNativeTarget "fish_indent" */ = {
|
||||||
isa = XCConfigurationList;
|
isa = XCConfigurationList;
|
||||||
buildConfigurations = (
|
buildConfigurations = (
|
||||||
|
|
|
@ -1,86 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<Scheme
|
|
||||||
LastUpgradeVersion = "0500"
|
|
||||||
version = "1.3">
|
|
||||||
<BuildAction
|
|
||||||
parallelizeBuildables = "YES"
|
|
||||||
buildImplicitDependencies = "YES">
|
|
||||||
<BuildActionEntries>
|
|
||||||
<BuildActionEntry
|
|
||||||
buildForTesting = "YES"
|
|
||||||
buildForRunning = "YES"
|
|
||||||
buildForProfiling = "YES"
|
|
||||||
buildForArchiving = "YES"
|
|
||||||
buildForAnalyzing = "YES">
|
|
||||||
<BuildableReference
|
|
||||||
BuildableIdentifier = "primary"
|
|
||||||
BlueprintIdentifier = "D0D02ABB15985EF9008E62BD"
|
|
||||||
BuildableName = "fishd"
|
|
||||||
BlueprintName = "fishd"
|
|
||||||
ReferencedContainer = "container:fish.xcodeproj">
|
|
||||||
</BuildableReference>
|
|
||||||
</BuildActionEntry>
|
|
||||||
</BuildActionEntries>
|
|
||||||
</BuildAction>
|
|
||||||
<TestAction
|
|
||||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
|
||||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
|
||||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
|
||||||
buildConfiguration = "Debug">
|
|
||||||
<Testables>
|
|
||||||
</Testables>
|
|
||||||
<MacroExpansion>
|
|
||||||
<BuildableReference
|
|
||||||
BuildableIdentifier = "primary"
|
|
||||||
BlueprintIdentifier = "D0D02ABB15985EF9008E62BD"
|
|
||||||
BuildableName = "fishd"
|
|
||||||
BlueprintName = "fishd"
|
|
||||||
ReferencedContainer = "container:fish.xcodeproj">
|
|
||||||
</BuildableReference>
|
|
||||||
</MacroExpansion>
|
|
||||||
</TestAction>
|
|
||||||
<LaunchAction
|
|
||||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
|
||||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
|
||||||
launchStyle = "0"
|
|
||||||
useCustomWorkingDirectory = "NO"
|
|
||||||
buildConfiguration = "Debug"
|
|
||||||
ignoresPersistentStateOnLaunch = "NO"
|
|
||||||
debugDocumentVersioning = "YES"
|
|
||||||
allowLocationSimulation = "YES">
|
|
||||||
<BuildableProductRunnable>
|
|
||||||
<BuildableReference
|
|
||||||
BuildableIdentifier = "primary"
|
|
||||||
BlueprintIdentifier = "D0D02ABB15985EF9008E62BD"
|
|
||||||
BuildableName = "fishd"
|
|
||||||
BlueprintName = "fishd"
|
|
||||||
ReferencedContainer = "container:fish.xcodeproj">
|
|
||||||
</BuildableReference>
|
|
||||||
</BuildableProductRunnable>
|
|
||||||
<AdditionalOptions>
|
|
||||||
</AdditionalOptions>
|
|
||||||
</LaunchAction>
|
|
||||||
<ProfileAction
|
|
||||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
|
||||||
savedToolIdentifier = ""
|
|
||||||
useCustomWorkingDirectory = "NO"
|
|
||||||
buildConfiguration = "Release"
|
|
||||||
debugDocumentVersioning = "YES">
|
|
||||||
<BuildableProductRunnable>
|
|
||||||
<BuildableReference
|
|
||||||
BuildableIdentifier = "primary"
|
|
||||||
BlueprintIdentifier = "D0D02ABB15985EF9008E62BD"
|
|
||||||
BuildableName = "fishd"
|
|
||||||
BlueprintName = "fishd"
|
|
||||||
ReferencedContainer = "container:fish.xcodeproj">
|
|
||||||
</BuildableReference>
|
|
||||||
</BuildableProductRunnable>
|
|
||||||
</ProfileAction>
|
|
||||||
<AnalyzeAction
|
|
||||||
buildConfiguration = "Debug">
|
|
||||||
</AnalyzeAction>
|
|
||||||
<ArchiveAction
|
|
||||||
buildConfiguration = "Release"
|
|
||||||
revealArchiveInOrganizer = "YES">
|
|
||||||
</ArchiveAction>
|
|
||||||
</Scheme>
|
|
971
fishd.cpp
971
fishd.cpp
|
@ -1,971 +0,0 @@
|
||||||
/** \file fishd.c
|
|
||||||
|
|
||||||
The universal variable server. fishd is automatically started by fish
|
|
||||||
if a fishd server isn't already running. fishd reads any saved
|
|
||||||
variables from ~/.fishd, and takes care of communication between fish
|
|
||||||
instances. When no clients are running, fishd will automatically shut
|
|
||||||
down and save.
|
|
||||||
|
|
||||||
\section fishd-commands Commands
|
|
||||||
|
|
||||||
Fishd works by sending and receiving commands. Each command is ended
|
|
||||||
with a newline. These are the commands supported by fishd:
|
|
||||||
|
|
||||||
<pre>set KEY:VALUE
|
|
||||||
set_export KEY:VALUE
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
These commands update the value of a variable. The only difference
|
|
||||||
between the two is that <tt>set_export</tt>-variables should be
|
|
||||||
exported to children of the process using them. When sending messages,
|
|
||||||
all values below 32 or above 127 must be escaped using C-style
|
|
||||||
backslash escapes. This means that the over the wire protocol is
|
|
||||||
ASCII. However, any conforming reader must also accept non-ascii
|
|
||||||
characters and interpret them as UTF-8. Lines containing invalid UTF-8
|
|
||||||
escape sequences must be ignored entirely.
|
|
||||||
|
|
||||||
<pre>erase KEY
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
Erase the variable with the specified name.
|
|
||||||
|
|
||||||
<pre>barrier
|
|
||||||
barrier_reply
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
A \c barrier command will result in a barrier_reply being added to
|
|
||||||
the end of the senders queue of unsent messages. These commands are
|
|
||||||
used to synchronize clients, since once the reply for a barrier
|
|
||||||
message returns, the sender can know that any updates available at the
|
|
||||||
time the original barrier request was sent have been received.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <wchar.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <sys/un.h>
|
|
||||||
#include <pwd.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
|
|
||||||
#ifdef HAVE_GETOPT_H
|
|
||||||
#include <getopt.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <locale.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <list>
|
|
||||||
|
|
||||||
#include "fallback.h"
|
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
#include "common.h"
|
|
||||||
#include "wutil.h"
|
|
||||||
#include "env_universal_common.h"
|
|
||||||
#include "path.h"
|
|
||||||
#include "print_help.h"
|
|
||||||
#include "fish_version.h"
|
|
||||||
|
|
||||||
#ifndef HOST_NAME_MAX
|
|
||||||
/**
|
|
||||||
Maximum length of hostname return. It is ok if this is too short,
|
|
||||||
getting the actual hostname is not critical, so long as the string
|
|
||||||
is unique in the filesystem namespace.
|
|
||||||
*/
|
|
||||||
#define HOST_NAME_MAX 255
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
Maximum length of socket filename
|
|
||||||
*/
|
|
||||||
#ifndef UNIX_PATH_MAX
|
|
||||||
#define UNIX_PATH_MAX 100
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
Fallback if MSG_DONTWAIT isn't defined. That's actually prerry bad,
|
|
||||||
and may lead to strange fishd behaviour, but at least it should
|
|
||||||
work most of the time.
|
|
||||||
*/
|
|
||||||
#ifndef MSG_DONTWAIT
|
|
||||||
#define MSG_DONTWAIT 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
Small greeting to show that fishd is running
|
|
||||||
*/
|
|
||||||
#define GREETING "# Fish universal variable daemon\n"
|
|
||||||
|
|
||||||
/**
|
|
||||||
Small not about not editing ~/.fishd manually. Inserted at the top of all .fishd files.
|
|
||||||
*/
|
|
||||||
#define SAVE_MSG "# This file is automatically generated by the fishd universal variable daemon.\n# Do NOT edit it directly, your changes will be overwritten.\n"
|
|
||||||
|
|
||||||
/**
|
|
||||||
The name of the save file. The machine identifier is appended to this.
|
|
||||||
*/
|
|
||||||
#define FILE "fishd."
|
|
||||||
|
|
||||||
/**
|
|
||||||
Maximum length of hostname. Longer hostnames are truncated
|
|
||||||
*/
|
|
||||||
#define HOSTNAME_LEN 32
|
|
||||||
|
|
||||||
/**
|
|
||||||
The string to append to the socket name to name the lockfile
|
|
||||||
*/
|
|
||||||
#define LOCKPOSTFIX ".lock"
|
|
||||||
|
|
||||||
/**
|
|
||||||
The timeout in seconds on the lockfile for critical section
|
|
||||||
*/
|
|
||||||
#define LOCKTIMEOUT 1
|
|
||||||
|
|
||||||
/**
|
|
||||||
Getopt short switches for fishd
|
|
||||||
*/
|
|
||||||
#define GETOPT_STRING "hv"
|
|
||||||
|
|
||||||
/**
|
|
||||||
The list of connections to clients
|
|
||||||
*/
|
|
||||||
typedef std::list<connection_t> connection_list_t;
|
|
||||||
static connection_list_t connections;
|
|
||||||
|
|
||||||
/**
|
|
||||||
The socket to accept new clients on
|
|
||||||
*/
|
|
||||||
static int sock;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Set to one when fishd should save and exit
|
|
||||||
*/
|
|
||||||
static int quit=0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Constructs the fish socket filename
|
|
||||||
*/
|
|
||||||
static std::string get_socket_filename(void)
|
|
||||||
{
|
|
||||||
const char *dir = getenv("FISHD_SOCKET_DIR");
|
|
||||||
char *uname = getenv("USER");
|
|
||||||
|
|
||||||
if (dir == NULL)
|
|
||||||
{
|
|
||||||
dir = "/tmp";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (uname == NULL)
|
|
||||||
{
|
|
||||||
const struct passwd *pw = getpwuid(getuid());
|
|
||||||
uname = pw->pw_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string name;
|
|
||||||
name.reserve(strlen(dir)+ strlen(uname)+ strlen(SOCK_FILENAME) + 1);
|
|
||||||
name.append(dir);
|
|
||||||
name.push_back('/');
|
|
||||||
name.append(SOCK_FILENAME);
|
|
||||||
name.append(uname);
|
|
||||||
|
|
||||||
if (name.size() >= UNIX_PATH_MAX)
|
|
||||||
{
|
|
||||||
debug(1, L"Filename too long: '%s'", name.c_str());
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Signal handler for the term signal.
|
|
||||||
*/
|
|
||||||
static void handle_term(int signal)
|
|
||||||
{
|
|
||||||
quit=1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Writes a pseudo-random number (between one and maxlen) of pseudo-random
|
|
||||||
digits into str.
|
|
||||||
str must point to an allocated buffer of size of at least maxlen chars.
|
|
||||||
Returns the number of digits written.
|
|
||||||
Since the randomness in part depends on machine time it has _some_ extra
|
|
||||||
strength but still not enough for use in concurrent locking schemes on a
|
|
||||||
single machine because gettimeofday may not return a different value on
|
|
||||||
consecutive calls when:
|
|
||||||
a) the OS does not support fine enough resolution
|
|
||||||
b) the OS is running on an SMP machine.
|
|
||||||
Additionally, gettimeofday errors are ignored.
|
|
||||||
Excludes chars other than digits since ANSI C only guarantees that digits
|
|
||||||
are consecutive.
|
|
||||||
*/
|
|
||||||
static void sprint_rand_digits(char *str, int maxlen)
|
|
||||||
{
|
|
||||||
int i, max;
|
|
||||||
struct timeval tv;
|
|
||||||
|
|
||||||
/*
|
|
||||||
Seed the pseudo-random generator based on time - this assumes
|
|
||||||
that consecutive calls to gettimeofday will return different values
|
|
||||||
and ignores errors returned by gettimeofday.
|
|
||||||
Cast to unsigned so that wrapping occurs on overflow as per ANSI C.
|
|
||||||
*/
|
|
||||||
static bool seeded = false;
|
|
||||||
if (! seeded)
|
|
||||||
{
|
|
||||||
(void)gettimeofday(&tv, NULL);
|
|
||||||
unsigned long long seed = tv.tv_sec + tv.tv_usec * 1000000ULL;
|
|
||||||
srand((unsigned int)seed);
|
|
||||||
seeded = true;
|
|
||||||
}
|
|
||||||
max = (int)(1 + (maxlen - 1) * (rand() / (RAND_MAX + 1.0)));
|
|
||||||
for (i = 0; i < max; i++)
|
|
||||||
{
|
|
||||||
str[i] = '0' + 10 * (rand() / (RAND_MAX + 1.0));
|
|
||||||
}
|
|
||||||
str[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Generate a filename unique in an NFS namespace by creating a copy of str and
|
|
||||||
appending .{hostname}.{pid} to it. If gethostname() fails then a pseudo-
|
|
||||||
random string is substituted for {hostname} - the randomness of the string
|
|
||||||
should be strong enough across different machines. The main assumption
|
|
||||||
though is that gethostname will not fail and this is just a "safe enough"
|
|
||||||
fallback.
|
|
||||||
The memory returned should be freed using free().
|
|
||||||
*/
|
|
||||||
static std::string gen_unique_nfs_filename(const std::string &filename)
|
|
||||||
{
|
|
||||||
char hostname[HOST_NAME_MAX + 1];
|
|
||||||
char pid_str[256];
|
|
||||||
snprintf(pid_str, sizeof pid_str, "%ld", (long)getpid());
|
|
||||||
|
|
||||||
if (gethostname(hostname, sizeof hostname) != 0)
|
|
||||||
{
|
|
||||||
sprint_rand_digits(hostname, HOST_NAME_MAX);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string newname(filename);
|
|
||||||
newname.push_back('.');
|
|
||||||
newname.append(hostname);
|
|
||||||
newname.push_back('.');
|
|
||||||
newname.append(pid_str);
|
|
||||||
return newname;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
The number of milliseconds to wait between polls when attempting to acquire
|
|
||||||
a lockfile
|
|
||||||
*/
|
|
||||||
#define LOCKPOLLINTERVAL 10
|
|
||||||
|
|
||||||
/**
|
|
||||||
Attempt to acquire a lock based on a lockfile, waiting LOCKPOLLINTERVAL
|
|
||||||
milliseconds between polls and timing out after timeout seconds,
|
|
||||||
thereafter forcibly attempting to obtain the lock if force is non-zero.
|
|
||||||
Returns 1 on success, 0 on failure.
|
|
||||||
To release the lock the lockfile must be unlinked.
|
|
||||||
A unique temporary file named by appending characters to the lockfile name
|
|
||||||
is used; any pre-existing file of the same name is subject to deletion.
|
|
||||||
*/
|
|
||||||
static int acquire_lock_file(const std::string &lockfile_str, const int timeout, int force)
|
|
||||||
{
|
|
||||||
int fd, timed_out = 0;
|
|
||||||
int ret = 0; /* early exit returns failure */
|
|
||||||
struct timespec pollint;
|
|
||||||
struct timeval start, end;
|
|
||||||
double elapsed;
|
|
||||||
struct stat statbuf;
|
|
||||||
const char * const lockfile = lockfile_str.c_str();
|
|
||||||
|
|
||||||
/*
|
|
||||||
(Re)create a unique file and check that it has one only link.
|
|
||||||
*/
|
|
||||||
const std::string linkfile_str = gen_unique_nfs_filename(lockfile);
|
|
||||||
const char * const linkfile = linkfile_str.c_str();
|
|
||||||
(void)unlink(linkfile);
|
|
||||||
/* OK to not use CLO_EXEC here because fishd is single threaded */
|
|
||||||
if ((fd = open(linkfile, O_CREAT|O_RDONLY, 0600)) == -1)
|
|
||||||
{
|
|
||||||
debug(1, L"acquire_lock_file: open: %s", strerror(errno));
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
Don't need to check exit status of close on read-only file descriptors
|
|
||||||
*/
|
|
||||||
close(fd);
|
|
||||||
if (stat(linkfile, &statbuf) != 0)
|
|
||||||
{
|
|
||||||
debug(1, L"acquire_lock_file: stat: %s", strerror(errno));
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
if (statbuf.st_nlink != 1)
|
|
||||||
{
|
|
||||||
debug(1, L"acquire_lock_file: number of hardlinks on unique "
|
|
||||||
L"tmpfile is %d instead of 1.", (int)statbuf.st_nlink);
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
if (gettimeofday(&start, NULL) != 0)
|
|
||||||
{
|
|
||||||
debug(1, L"acquire_lock_file: gettimeofday: %s", strerror(errno));
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
end = start;
|
|
||||||
pollint.tv_sec = 0;
|
|
||||||
pollint.tv_nsec = LOCKPOLLINTERVAL * 1000000;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
Try to create a hard link to the unique file from the
|
|
||||||
lockfile. This will only succeed if the lockfile does not
|
|
||||||
already exist. It is guaranteed to provide race-free
|
|
||||||
semantics over NFS which the alternative of calling
|
|
||||||
open(O_EXCL|O_CREAT) on the lockfile is not. The lock
|
|
||||||
succeeds if the call to link returns 0 or the link count on
|
|
||||||
the unique file increases to 2.
|
|
||||||
*/
|
|
||||||
if (link(linkfile, lockfile) == 0 ||
|
|
||||||
(stat(linkfile, &statbuf) == 0 &&
|
|
||||||
statbuf.st_nlink == 2))
|
|
||||||
{
|
|
||||||
/* Successful lock */
|
|
||||||
ret = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
elapsed = end.tv_sec + end.tv_usec/1000000.0 -
|
|
||||||
(start.tv_sec + start.tv_usec/1000000.0);
|
|
||||||
/*
|
|
||||||
The check for elapsed < 0 is to deal with the unlikely event
|
|
||||||
that after the loop is entered the system time is set forward
|
|
||||||
past the loop's end time. This would otherwise result in a
|
|
||||||
(practically) infinite loop.
|
|
||||||
*/
|
|
||||||
if (timed_out || elapsed >= timeout || elapsed < 0)
|
|
||||||
{
|
|
||||||
if (timed_out == 0 && force)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
Timed out and force was specified - attempt to
|
|
||||||
remove stale lock and try a final time
|
|
||||||
*/
|
|
||||||
(void)unlink(lockfile);
|
|
||||||
timed_out = 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
Timed out and final try was unsuccessful or
|
|
||||||
force was not specified
|
|
||||||
*/
|
|
||||||
debug(1, L"acquire_lock_file: timed out "
|
|
||||||
L"trying to obtain lockfile %s using "
|
|
||||||
L"linkfile %s", lockfile, linkfile);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
nanosleep(&pollint, NULL);
|
|
||||||
}
|
|
||||||
while (gettimeofday(&end, NULL) == 0);
|
|
||||||
done:
|
|
||||||
/* The linkfile is not needed once the lockfile has been created */
|
|
||||||
(void)unlink(linkfile);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Acquire the lock for the socket
|
|
||||||
Returns the name of the lock file if successful or
|
|
||||||
NULL if unable to obtain lock.
|
|
||||||
The returned string must be free()d after unlink()ing the file to release
|
|
||||||
the lock
|
|
||||||
*/
|
|
||||||
static bool acquire_socket_lock(const std::string &sock_name, std::string *out_lockfile_name)
|
|
||||||
{
|
|
||||||
bool success = false;
|
|
||||||
std::string lockfile;
|
|
||||||
lockfile.reserve(sock_name.size() + strlen(LOCKPOSTFIX));
|
|
||||||
lockfile = sock_name;
|
|
||||||
lockfile.append(LOCKPOSTFIX);
|
|
||||||
if (acquire_lock_file(lockfile, LOCKTIMEOUT, 1))
|
|
||||||
{
|
|
||||||
out_lockfile_name->swap(lockfile);
|
|
||||||
success = true;
|
|
||||||
}
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Connects to the fish socket and starts listening for connections
|
|
||||||
*/
|
|
||||||
static int get_socket(void)
|
|
||||||
{
|
|
||||||
// Cygwin has random problems involving sockets. When using Cygwin,
|
|
||||||
// allow 20 attempts at making socket correctly.
|
|
||||||
#ifdef __CYGWIN__
|
|
||||||
int attempts = 0;
|
|
||||||
repeat:
|
|
||||||
attempts += 1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int s, len, doexit = 0;
|
|
||||||
int exitcode = EXIT_FAILURE;
|
|
||||||
struct sockaddr_un local;
|
|
||||||
const std::string sock_name = get_socket_filename();
|
|
||||||
|
|
||||||
/*
|
|
||||||
Start critical section protected by lock
|
|
||||||
*/
|
|
||||||
std::string lockfile;
|
|
||||||
if (! acquire_socket_lock(sock_name, &lockfile))
|
|
||||||
{
|
|
||||||
debug(0, L"Unable to obtain lock on socket, exiting");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
debug(4, L"Acquired lockfile: %s", lockfile.c_str());
|
|
||||||
|
|
||||||
local.sun_family = AF_UNIX;
|
|
||||||
strcpy(local.sun_path, sock_name.c_str());
|
|
||||||
len = sizeof(local);
|
|
||||||
|
|
||||||
debug(1, L"Connect to socket at %s", sock_name.c_str());
|
|
||||||
|
|
||||||
if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
|
|
||||||
{
|
|
||||||
wperror(L"socket");
|
|
||||||
doexit = 1;
|
|
||||||
goto unlock;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
First check whether the socket has been opened by another fishd;
|
|
||||||
if so, exit with success status
|
|
||||||
*/
|
|
||||||
if (connect(s, (struct sockaddr *)&local, len) == 0)
|
|
||||||
{
|
|
||||||
debug(1, L"Socket already exists, exiting");
|
|
||||||
doexit = 1;
|
|
||||||
exitcode = 0;
|
|
||||||
goto unlock;
|
|
||||||
}
|
|
||||||
|
|
||||||
unlink(local.sun_path);
|
|
||||||
if (bind(s, (struct sockaddr *)&local, len) == -1)
|
|
||||||
{
|
|
||||||
wperror(L"bind");
|
|
||||||
doexit = 1;
|
|
||||||
goto unlock;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (make_fd_nonblocking(s) != 0)
|
|
||||||
{
|
|
||||||
wperror(L"fcntl");
|
|
||||||
close(s);
|
|
||||||
doexit = 1;
|
|
||||||
}
|
|
||||||
else if (listen(s, 64) == -1)
|
|
||||||
{
|
|
||||||
wperror(L"listen");
|
|
||||||
doexit = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
unlock:
|
|
||||||
(void)unlink(lockfile.c_str());
|
|
||||||
debug(4, L"Released lockfile: %s", lockfile.c_str());
|
|
||||||
/*
|
|
||||||
End critical section protected by lock
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (doexit)
|
|
||||||
{
|
|
||||||
// If Cygwin, only allow normal quit when made lots of attempts.
|
|
||||||
#ifdef __CYGWIN__
|
|
||||||
if (exitcode && attempts < 20) goto repeat;
|
|
||||||
#endif
|
|
||||||
exit_without_destructors(exitcode);
|
|
||||||
}
|
|
||||||
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Event handler. Broadcasts updates to all clients.
|
|
||||||
*/
|
|
||||||
static void broadcast(fish_message_type_t type, const wchar_t *key, const wchar_t *val)
|
|
||||||
{
|
|
||||||
message_t *msg;
|
|
||||||
|
|
||||||
if (connections.empty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
msg = create_message(type, key, val);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Don't merge these loops, or try_send_all can free the message
|
|
||||||
prematurely
|
|
||||||
*/
|
|
||||||
|
|
||||||
for (connection_list_t::iterator iter = connections.begin(); iter != connections.end(); ++iter)
|
|
||||||
{
|
|
||||||
msg->count++;
|
|
||||||
iter->unsent.push(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (connection_list_t::iterator iter = connections.begin(); iter != connections.end(); ++iter)
|
|
||||||
{
|
|
||||||
try_send_all(&*iter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Make program into a creature of the night.
|
|
||||||
*/
|
|
||||||
static void daemonize()
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
Fork, and let parent exit
|
|
||||||
*/
|
|
||||||
switch (fork())
|
|
||||||
{
|
|
||||||
case -1:
|
|
||||||
debug(0, L"Could not put fishd in background. Quitting");
|
|
||||||
wperror(L"fork");
|
|
||||||
exit(1);
|
|
||||||
|
|
||||||
case 0:
|
|
||||||
{
|
|
||||||
/* Ordinarily there's very limited things we will do after fork, due to multithreading. But fishd is safe because it's single threaded. So don't die in is_forked_child. */
|
|
||||||
setup_fork_guards();
|
|
||||||
|
|
||||||
/*
|
|
||||||
Make fishd ignore the HUP and PIPE signals.
|
|
||||||
*/
|
|
||||||
struct sigaction act;
|
|
||||||
sigemptyset(& act.sa_mask);
|
|
||||||
act.sa_flags=0;
|
|
||||||
act.sa_handler=SIG_IGN;
|
|
||||||
sigaction(SIGHUP, &act, 0);
|
|
||||||
sigaction(SIGPIPE, &act, 0);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Make fishd save and exit on the TERM signal.
|
|
||||||
*/
|
|
||||||
sigfillset(& act.sa_mask);
|
|
||||||
act.sa_flags=0;
|
|
||||||
act.sa_handler=&handle_term;
|
|
||||||
sigaction(SIGTERM, &act, 0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
debug(0, L"Parent process exiting (This is normal)");
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Put ourself in our own process group
|
|
||||||
*/
|
|
||||||
setsid();
|
|
||||||
|
|
||||||
/*
|
|
||||||
Close stdin and stdout. We only use stderr, anyway.
|
|
||||||
*/
|
|
||||||
close(0);
|
|
||||||
close(1);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Get environment variable value.
|
|
||||||
*/
|
|
||||||
static env_var_t fishd_env_get(const char *key)
|
|
||||||
{
|
|
||||||
const char *env = getenv(key);
|
|
||||||
if (env != NULL)
|
|
||||||
{
|
|
||||||
return env_var_t(str2wcstring(env));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const wcstring wkey = str2wcstring(key);
|
|
||||||
return env_universal_common_get(wkey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Get the configuration directory. The resulting string needs to be
|
|
||||||
free'd. This is mostly the same code as path_get_config(), but had
|
|
||||||
to be rewritten to avoid dragging in additional library
|
|
||||||
dependencies.
|
|
||||||
*/
|
|
||||||
static wcstring fishd_get_config()
|
|
||||||
{
|
|
||||||
bool done = false;
|
|
||||||
wcstring result;
|
|
||||||
|
|
||||||
env_var_t xdg_dir = fishd_env_get("XDG_CONFIG_HOME");
|
|
||||||
if (! xdg_dir.missing_or_empty())
|
|
||||||
{
|
|
||||||
result = xdg_dir;
|
|
||||||
append_path_component(result, L"/fish");
|
|
||||||
if (!create_directory(result))
|
|
||||||
{
|
|
||||||
done = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
env_var_t home = fishd_env_get("HOME");
|
|
||||||
if (! home.missing_or_empty())
|
|
||||||
{
|
|
||||||
result = home;
|
|
||||||
append_path_component(result, L"/.config/fish");
|
|
||||||
if (!create_directory(result))
|
|
||||||
{
|
|
||||||
done = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! done)
|
|
||||||
{
|
|
||||||
/* Bad juju */
|
|
||||||
debug(0, _(L"Unable to create a configuration directory for fish. Your personal settings will not be saved. Please set the $XDG_CONFIG_HOME variable to a directory where the current user has write access."));
|
|
||||||
result.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Load or save all variables
|
|
||||||
*/
|
|
||||||
static bool load_or_save_variables_at_path(bool save, const std::string &path)
|
|
||||||
{
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
debug(4, L"Open file for %s: '%s'",
|
|
||||||
save?"saving":"loading",
|
|
||||||
path.c_str());
|
|
||||||
|
|
||||||
/* OK to not use CLO_EXEC here because fishd is single threaded */
|
|
||||||
int fd = open(path.c_str(), save?(O_CREAT | O_TRUNC | O_WRONLY):O_RDONLY, 0600);
|
|
||||||
if (fd >= 0)
|
|
||||||
{
|
|
||||||
/* Success */
|
|
||||||
result = true;
|
|
||||||
connection_t c(fd);
|
|
||||||
|
|
||||||
if (save)
|
|
||||||
{
|
|
||||||
/* Save to the file */
|
|
||||||
write_loop(c.fd, SAVE_MSG, strlen(SAVE_MSG));
|
|
||||||
enqueue_all(&c);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Read from the file */
|
|
||||||
read_message(&c);
|
|
||||||
}
|
|
||||||
|
|
||||||
connection_destroy(&c);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static std::string get_variables_file_path(const std::string &dir, const std::string &identifier)
|
|
||||||
{
|
|
||||||
std::string name;
|
|
||||||
name.append(dir);
|
|
||||||
name.append("/");
|
|
||||||
name.append(FILE);
|
|
||||||
name.append(identifier);
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static bool load_or_save_variables(bool save)
|
|
||||||
{
|
|
||||||
const wcstring wdir = fishd_get_config();
|
|
||||||
const std::string dir = wcs2string(wdir);
|
|
||||||
if (dir.empty())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const std::string machine_id = get_machine_identifier();
|
|
||||||
const std::string machine_id_path = get_variables_file_path(dir, machine_id);
|
|
||||||
bool success = load_or_save_variables_at_path(save, machine_id_path);
|
|
||||||
if (! success && ! save && errno == ENOENT)
|
|
||||||
{
|
|
||||||
/* We failed to load, because the file was not found. Older fish used the hostname only. Try *moving* the filename based on the hostname into place; if that succeeds try again. Silently "upgraded." */
|
|
||||||
std::string hostname_id;
|
|
||||||
if (get_hostname_identifier(&hostname_id) && hostname_id != machine_id)
|
|
||||||
{
|
|
||||||
std::string hostname_path = get_variables_file_path(dir, hostname_id);
|
|
||||||
if (0 == rename(hostname_path.c_str(), machine_id_path.c_str()))
|
|
||||||
{
|
|
||||||
/* We renamed - try again */
|
|
||||||
success = load_or_save_variables_at_path(save, machine_id_path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Load variables from disk
|
|
||||||
*/
|
|
||||||
static void load()
|
|
||||||
{
|
|
||||||
load_or_save_variables(false /* load, not save */);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Save variables to disk
|
|
||||||
*/
|
|
||||||
static void save()
|
|
||||||
{
|
|
||||||
load_or_save_variables(true /* save, not load */);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Do all sorts of boring initialization.
|
|
||||||
*/
|
|
||||||
static void init()
|
|
||||||
{
|
|
||||||
|
|
||||||
sock = get_socket();
|
|
||||||
daemonize();
|
|
||||||
env_universal_common_init(&broadcast);
|
|
||||||
|
|
||||||
load();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Main function for fishd
|
|
||||||
*/
|
|
||||||
int main(int argc, char ** argv)
|
|
||||||
{
|
|
||||||
int child_socket;
|
|
||||||
struct sockaddr_un remote;
|
|
||||||
socklen_t t;
|
|
||||||
uid_t sock_euid;
|
|
||||||
gid_t sock_egid;
|
|
||||||
int max_fd;
|
|
||||||
int update_count=0;
|
|
||||||
|
|
||||||
fd_set read_fd, write_fd;
|
|
||||||
|
|
||||||
set_main_thread();
|
|
||||||
setup_fork_guards();
|
|
||||||
|
|
||||||
program_name=L"fishd";
|
|
||||||
wsetlocale(LC_ALL, L"");
|
|
||||||
|
|
||||||
/*
|
|
||||||
Parse options
|
|
||||||
*/
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
static struct option
|
|
||||||
long_options[] =
|
|
||||||
{
|
|
||||||
{
|
|
||||||
"help", no_argument, 0, 'h'
|
|
||||||
}
|
|
||||||
,
|
|
||||||
{
|
|
||||||
"version", no_argument, 0, 'v'
|
|
||||||
}
|
|
||||||
,
|
|
||||||
{
|
|
||||||
0, 0, 0, 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
int opt_index = 0;
|
|
||||||
|
|
||||||
int opt = getopt_long(argc,
|
|
||||||
argv,
|
|
||||||
GETOPT_STRING,
|
|
||||||
long_options,
|
|
||||||
&opt_index);
|
|
||||||
|
|
||||||
if (opt == -1)
|
|
||||||
break;
|
|
||||||
|
|
||||||
switch (opt)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'h':
|
|
||||||
print_help(argv[0], 1);
|
|
||||||
exit(0);
|
|
||||||
|
|
||||||
case 'v':
|
|
||||||
debug(0, L"%ls, version %s\n", program_name, get_fish_version());
|
|
||||||
exit(0);
|
|
||||||
|
|
||||||
case '?':
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
init();
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
int res;
|
|
||||||
|
|
||||||
t = sizeof(remote);
|
|
||||||
|
|
||||||
FD_ZERO(&read_fd);
|
|
||||||
FD_ZERO(&write_fd);
|
|
||||||
FD_SET(sock, &read_fd);
|
|
||||||
max_fd = sock+1;
|
|
||||||
for (connection_list_t::const_iterator iter = connections.begin(); iter != connections.end(); ++iter)
|
|
||||||
{
|
|
||||||
const connection_t &c = *iter;
|
|
||||||
FD_SET(c.fd, &read_fd);
|
|
||||||
max_fd = maxi(max_fd, c.fd+1);
|
|
||||||
|
|
||||||
if (! c.unsent.empty())
|
|
||||||
{
|
|
||||||
FD_SET(c.fd, &write_fd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
res=select(max_fd, &read_fd, &write_fd, 0, 0);
|
|
||||||
|
|
||||||
if (quit)
|
|
||||||
{
|
|
||||||
save();
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res != -1)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (errno != EINTR)
|
|
||||||
{
|
|
||||||
wperror(L"select");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FD_ISSET(sock, &read_fd))
|
|
||||||
{
|
|
||||||
if ((child_socket =
|
|
||||||
accept(sock,
|
|
||||||
(struct sockaddr *)&remote,
|
|
||||||
&t)) == -1)
|
|
||||||
{
|
|
||||||
wperror(L"accept");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
debug(4, L"Connected with new child on fd %d", child_socket);
|
|
||||||
|
|
||||||
if (((getpeereid(child_socket, &sock_euid, &sock_egid) != 0) || sock_euid != geteuid()))
|
|
||||||
{
|
|
||||||
debug(1, L"Wrong credentials for child on fd %d", child_socket);
|
|
||||||
close(child_socket);
|
|
||||||
}
|
|
||||||
else if (make_fd_nonblocking(child_socket) != 0)
|
|
||||||
{
|
|
||||||
wperror(L"fcntl");
|
|
||||||
close(child_socket);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
connections.push_front(connection_t(child_socket));
|
|
||||||
connection_t &newc = connections.front();
|
|
||||||
send(newc.fd, GREETING, strlen(GREETING), MSG_DONTWAIT);
|
|
||||||
enqueue_all(&newc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (connection_list_t::iterator iter = connections.begin(); iter != connections.end(); ++iter)
|
|
||||||
{
|
|
||||||
if (FD_ISSET(iter->fd, &write_fd))
|
|
||||||
{
|
|
||||||
try_send_all(&*iter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (connection_list_t::iterator iter = connections.begin(); iter != connections.end(); ++iter)
|
|
||||||
{
|
|
||||||
if (FD_ISSET(iter->fd, &read_fd))
|
|
||||||
{
|
|
||||||
read_message(&*iter);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Occasionally we save during normal use, so that we
|
|
||||||
won't lose everything on a system crash
|
|
||||||
*/
|
|
||||||
update_count++;
|
|
||||||
if (update_count >= 64)
|
|
||||||
{
|
|
||||||
save();
|
|
||||||
update_count = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (connection_list_t::iterator iter = connections.begin(); iter != connections.end();)
|
|
||||||
{
|
|
||||||
if (iter->killme)
|
|
||||||
{
|
|
||||||
debug(4, L"Close connection %d", iter->fd);
|
|
||||||
|
|
||||||
while (! iter->unsent.empty())
|
|
||||||
{
|
|
||||||
message_t *msg = iter->unsent.front();
|
|
||||||
iter->unsent.pop();
|
|
||||||
msg->count--;
|
|
||||||
if (! msg->count)
|
|
||||||
free(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
connection_destroy(&*iter);
|
|
||||||
iter = connections.erase(iter);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
++iter;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (connections.empty())
|
|
||||||
{
|
|
||||||
debug(0, L"No more clients. Quitting");
|
|
||||||
save();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue