TNT/docs/CONTRIBUTING.md

2.8 KiB

HACKING

Build

make                    # normal build
make debug              # with symbols
make asan               # AddressSanitizer
make release            # optimized
make release-check      # release preflight

Test

make test                 # unit + integration tests
make ci-test              # local CI-equivalent checks
make stress-test          # concurrent-client stress test

Debug

# Memory leaks
ASAN_OPTIONS=detect_leaks=1 ./tnt

# Or use valgrind
make valgrind
valgrind --leak-check=full ./tnt

# Static analysis
make check

Architecture

main.c           → entry point, signal handling
cli_text.c       → startup CLI text
command_catalog.c → COMMAND-mode command metadata, usage, and argument shape
commands.c       → COMMAND-mode command dispatch
exec_catalog.c   → SSH exec command matching, usage, and argument shape
exec.c           → SSH exec command dispatch
ssh_server.c     → SSH listener setup
bootstrap.c      → SSH authentication/session bootstrap
input.c          → interactive session loop
chat_room.c      → client list, message broadcast
history_view.c   → message viewport and scroll state
i18n.c           → UI language and locale selection
i18n_text.c      → shared UI text catalog
message.c        → persistent storage
tui.c            → terminal rendering
tui_status.c     → status/input-line rendering
utf8.c           → UTF-8 string handling

Thread Safety

  • g_room->lock: RWlock for client list and messages
  • client->ref_lock: Mutex for reference counting
  • Each client runs in detached thread
  • Reference counting prevents use-after-free

Memory Management

  • Clients: ref-counted, freed when ref==0
  • Messages: fixed ring buffer (MAX_MESSAGES)
  • No dynamic string allocation

Known Limits

  • Max 64 clients (MAX_CLIENTS)
  • Max 100 messages in memory (MAX_MESSAGES)
  • Max 1024 bytes per message (MAX_MESSAGE_LEN)
  • Max 64 bytes username (MAX_USERNAME_LEN)

Common Bugs to Avoid

  1. Don't use strtok() on client data - use strtok_r() or copy first
  2. Always increment ref_count before using client outside lock
  3. Check SSH API return values (can be SSH_ERROR, SSH_AGAIN, or negative)
  4. UTF-8 chars are multi-byte - use utf8_* functions

Adding Features

  1. Add interactive command metadata, usage text, and argument shape in src/command_catalog.c.
  2. Add interactive command behavior in src/commands.c.
  3. Add SSH exec metadata in src/exec_catalog.c and dispatch in src/exec.c only when the feature should be scriptable.
  4. Put shared localized strings in src/i18n_text.c.
  5. Add or update the narrowest unit/integration test for the behavior.

Debugging Tips

# Find memory issues
make asan
ASAN_OPTIONS=detect_leaks=1:abort_on_error=1 ./tnt

# Check thread issues
gcc -fsanitize=thread ...

# Profile
gcc -pg ...
./tnt
gprof tnt