diff options
author | P. J. McDermott <pj@pehjota.net> | 2016-02-22 15:43:21 (EST) |
---|---|---|
committer | P. J. McDermott <pj@pehjota.net> | 2016-02-22 15:43:21 (EST) |
commit | 36cf5f8c449b67665b240e51731f903ebe146e8e (patch) | |
tree | 5f1f03c94f68a9a7505723313ff8533bf3bbae3a /eshld/link.esh | |
parent | 18edfbff2c030ac2757c5ff295ed48cf919d37e8 (diff) | |
download | eggshell-36cf5f8c449b67665b240e51731f903ebe146e8e.zip eggshell-36cf5f8c449b67665b240e51731f903ebe146e8e.tar.gz eggshell-36cf5f8c449b67665b240e51731f903ebe146e8e.tar.bz2 |
Add basic eshld
Diffstat (limited to 'eshld/link.esh')
-rw-r--r-- | eshld/link.esh | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/eshld/link.esh b/eshld/link.esh new file mode 100644 index 0000000..d01fc4d --- /dev/null +++ b/eshld/link.esh @@ -0,0 +1,102 @@ +# Eggshell Linker entry point +# +# Copyright (C) 2015 Patrick "P. J." McDermott +# +# This file is part of the Eggshell Linker. +# +# The Eggshell Linker is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, either version 3 of +# the License, or (at your option) any later version. +# +# The Eggshell Linker is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with the Eggshell Linker If not, see +# <http://www.gnu.org/licenses/>. + +interpreter= +entry_point= +output= +make_executable= + +die() +{ + local fmt="${1}" + shift 1 + + printf "eshld: ${fmt}\n" "${@}" >&2 + exit 2 +} + +link_begin() +{ + local interp="${1}" + local entry="${2}" + local out="${3}" + local mkexec="${4}" + shift 4 + + interpreter="${interp}" + entry_point="${entry}" + output="${out}" + make_executable=${mkexec} + + # Open output file. + if ! exec 3>"${output}~"; then + die 'Cannot open file "%s"' "${output}~" + fi + + # Write magic number and interpreter path. + if ${make_executable}; then + printf '#!%s\n' "${interpreter}" >&3 + fi + + # Write __init() function. + cat >&3 <<-'EOF' + __init_funcs='' + __init() + { + __init_funcs="${__init_funcs} ${1}" + } + EOF + +} + +link_file() +{ + local input="${1}" + + if ! cat "${input}" >&3; then + die 'Cannot read file "%s"' "${input}" + fi +} + +link_end() +{ + # Add call to init functions. + cat >&3 <<-'EOF' + for __func in ${__init_funcs}; do + ${__func} + done + EOF + + # Add call to entry point. + if ${make_executable}; then + printf '%s "${@}"\n' "${entry_point}" >&3 + fi + + # Close output file, make it executable, and set its name. + exec 3>&- + if ${make_executable}; then + if ! chmod a+x "${output}~"; then + die 'Cannot set mode of file "%s"' "${output}~" + fi + fi + if ! mv "${output}~" "${output}"; then + die 'Cannot rename file to "%s"' "${output}" + fi +} |