Skip to content

Commit

Permalink
Add isatty/1 NIF [WIP]
Browse files Browse the repository at this point in the history
  • Loading branch information
dumbbell committed Dec 10, 2019
1 parent f5ee4d8 commit e9849f1
Show file tree
Hide file tree
Showing 5 changed files with 175 additions and 8 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
*.o
/_build/
/doc/
/priv/
/rebar.lock
74 changes: 74 additions & 0 deletions c_src/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Based on c_src.mk from erlang.mk by Loic Hoguin <essen@ninenines.eu>

CURDIR := $(shell pwd)
BASEDIR := $(abspath $(CURDIR)/..)

PROJECT ?= $(notdir $(BASEDIR))
PROJECT := $(strip $(PROJECT))

ERTS_INCLUDE_DIR ?= $(shell erl -noshell -s init stop -eval "io:format(\"~ts/erts-~ts/include/\", [code:root_dir(), erlang:system_info(version)]).")
ERL_INTERFACE_INCLUDE_DIR ?= $(shell erl -noshell -s init stop -eval "io:format(\"~ts\", [code:lib_dir(erl_interface, include)]).")
ERL_INTERFACE_LIB_DIR ?= $(shell erl -noshell -s init stop -eval "io:format(\"~ts\", [code:lib_dir(erl_interface, lib)]).")

C_SRC_DIR = $(CURDIR)
C_SRC_OUTPUT ?= $(CURDIR)/../priv/$(PROJECT).so

# System type and C compiler/flags.

UNAME_SYS := $(shell uname -s)
ifeq ($(UNAME_SYS), Darwin)
CC ?= cc
CFLAGS ?= -O3 -std=c99 -arch x86_64 -finline-functions -Wall -Wmissing-prototypes
CXXFLAGS ?= -O3 -arch x86_64 -finline-functions -Wall
LDFLAGS ?= -arch x86_64 -flat_namespace -undefined suppress
else ifeq ($(UNAME_SYS), FreeBSD)
CC ?= cc
CFLAGS ?= -O3 -std=c99 -finline-functions -Wall -Wmissing-prototypes
CXXFLAGS ?= -O3 -finline-functions -Wall
else ifeq ($(UNAME_SYS), Linux)
CC ?= gcc
CFLAGS ?= -O3 -std=c99 -finline-functions -Wall -Wmissing-prototypes
CXXFLAGS ?= -O3 -finline-functions -Wall
endif

CFLAGS += -fPIC -I $(ERTS_INCLUDE_DIR) -I $(ERL_INTERFACE_INCLUDE_DIR)
CXXFLAGS += -fPIC -I $(ERTS_INCLUDE_DIR) -I $(ERL_INTERFACE_INCLUDE_DIR)

LDLIBS += -L $(ERL_INTERFACE_LIB_DIR) -lerl_interface -lei
LDFLAGS += -shared

# Verbosity.

c_verbose_0 = @echo " C " $(?F);
c_verbose = $(c_verbose_$(V))

cpp_verbose_0 = @echo " CPP " $(?F);
cpp_verbose = $(cpp_verbose_$(V))

link_verbose_0 = @echo " LD " $(@F);
link_verbose = $(link_verbose_$(V))

SOURCES := $(shell find $(C_SRC_DIR) -type f \( -name "*.c" -o -name "*.C" -o -name "*.cc" -o -name "*.cpp" \))
OBJECTS = $(addsuffix .o, $(basename $(SOURCES)))

COMPILE_C = $(c_verbose) $(CC) $(CFLAGS) $(CPPFLAGS) -c
COMPILE_CPP = $(cpp_verbose) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c

$(C_SRC_OUTPUT): $(OBJECTS)
@mkdir -p $(dir $(C_SRC_OUTPUT))
$(link_verbose) $(CC) $(OBJECTS) $(LDFLAGS) $(LDLIBS) -o $(C_SRC_OUTPUT)

%.o: %.c
$(COMPILE_C) $(OUTPUT_OPTION) $<

%.o: %.cc
$(COMPILE_CPP) $(OUTPUT_OPTION) $<

%.o: %.C
$(COMPILE_CPP) $(OUTPUT_OPTION) $<

%.o: %.cpp
$(COMPILE_CPP) $(OUTPUT_OPTION) $<

clean:
@rm -f $(C_SRC_OUTPUT) $(OBJECTS)
44 changes: 44 additions & 0 deletions c_src/stdout_formatter_nifs.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#include <string.h>
#include <unistd.h>

#include "erl_nif.h"

static ERL_NIF_TERM
isatty_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
int ret, fd;
char atom_arg[10];

if (argc != 1) {
return enif_make_badarg(env);
}

if (!enif_is_atom(env, argv[0])) {
return enif_make_badarg(env);
}

ret = enif_get_atom(env, argv[0], atom_arg, (unsigned int)sizeof(atom_arg),
ERL_NIF_LATIN1);
if (ret == 0) {
return enif_make_badarg(env);
}

if (strcmp(atom_arg, "stdin") == 0) {
fd = 0;
} else if (strcmp(atom_arg, "stdout") == 0) {
fd = 1;
} else if (strcmp(atom_arg, "stderr") == 0) {
fd = 2;
} else {
return enif_make_badarg(env);
}

ret = isatty(fd);
return enif_make_atom(env, ret ? "true" : "false");
}

static ErlNifFunc nif_funcs[] = {
{"isatty", 1, isatty_nif}
};

ERL_NIF_INIT(stdout_formatter_nifs, nif_funcs, NULL, NULL, NULL, NULL);
45 changes: 37 additions & 8 deletions rebar.config.script
Original file line number Diff line number Diff line change
@@ -1,15 +1,44 @@
%% vim:ft=erlang:

Make = case os:find_executable("gmake") of
false -> "make";
Value -> Value
end,

C_SRC_OUTPUT = filename:join(
[filename:absname(filename:dirname(SCRIPT)),
"priv",
erlang:system_info(system_architecture),
"stdout_formatter_nifs.so"]),

CONFIG1 = [{pre_hooks,
[{compile,
lists:flatten(
io_lib:format(
"~s -C c_src"
" C_SRC_OUTPUT=~s",
[Make, C_SRC_OUTPUT]))}]},
{post_hooks,
[{clean,
lists:flatten(
io_lib:format(
"~s -C c_src"
" C_SRC_OUTPUT=~s"
" clean",
[Make, C_SRC_OUTPUT]))}]}
| CONFIG],

case os:getenv("TRAVIS_JOB_ID") of
false -> CONFIG;
false -> CONFIG1;
JobId ->
%% coveralls.io.
[{plugins, [{coveralls,
{git, "https://github.com/markusn/coveralls-erl",
{branch, "master"}}}]}
,{coveralls_coverdata, "_build/test/cover/eunit.coverdata"}
,{coveralls_service_name, "travis-ci"}
,{coveralls_service_job_id, JobId}
|CONFIG
[{plugins,
[{coveralls,
{git, "https://github.com/markusn/coveralls-erl",
{branch, "master"}}}]},
{coveralls_coverdata, "_build/test/cover/eunit.coverdata"},
{coveralls_service_name, "travis-ci"},
{coveralls_service_job_id, JobId}
| CONFIG1
]
end.
18 changes: 18 additions & 0 deletions src/stdout_formatter_nifs.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
-module(stdout_formatter_nifs).

-export([isatty/1]).

-on_load(on_load/0).

on_load() ->
Lib = filename:join(
[code:priv_dir(stdout_formatter),
erlang:system_info(system_architecture),
"stdout_formatter_nifs"]),
ok = erlang:load_nif(Lib, 0).

isatty(Fd)
when Fd =:= stdin orelse
Fd =:= stdout orelse
Fd =:= stderr ->
undefined.

0 comments on commit e9849f1

Please sign in to comment.