Skip to content

Instantly share code, notes, and snippets.

@StefanoBelli
Last active November 12, 2025 07:55
Show Gist options
  • Select an option

  • Save StefanoBelli/947298ee55ed6b46828d3dfeb1a32f6a to your computer and use it in GitHub Desktop.

Select an option

Save StefanoBelli/947298ee55ed6b46828d3dfeb1a32f6a to your computer and use it in GitHub Desktop.
Example of getty program
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <getopt.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
static int do_dup(int fd, int newfd) {
int dupped_fd = dup3(fd, newfd, 0);
if(dupped_fd < 0 && errno != EINVAL) {
return -1;
}
return !(dupped_fd == newfd);
}
static int get_the_tty(const char* tty) {
int fd_tty = open(tty, O_RDWR);
if(fd_tty < 0) {
goto __get_the_tty_ret0;
}
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
if(do_dup(fd_tty, STDIN_FILENO) != 0) {
goto __get_the_tty_ret1;
}
if(do_dup(fd_tty, STDOUT_FILENO) != 0) {
goto __get_the_tty_ret1;
}
if(do_dup(fd_tty, STDERR_FILENO) != 0) {
goto __get_the_tty_ret1;
}
if(fd_tty > STDERR_FILENO) {
close(fd_tty);
}
if(!isatty(STDIN_FILENO)) {
perror("isatty");
goto __get_the_tty_ret0;
}
if(ioctl(STDIN_FILENO, TIOCSCTTY, 0) != 0) {
perror("ioctl");
goto __get_the_tty_ret0;
}
return STDIN_FILENO;
__get_the_tty_ret1:
close(fd_tty);
__get_the_tty_ret0:
return -1;
}
int main(int argc, char** argv) {
char *tty;
int opt;
while((opt = getopt(argc, argv, "t:")) != -1) {
switch(opt) {
case 't':
tty = optarg;
break;
}
}
if(setsid() < 0 && errno != EPERM) {
exit(11);
}
int tty_fd = get_the_tty(tty);
if(tty_fd < 0) {
exit(22);
}
if(tcsetpgrp(tty_fd, getpgrp()) != 0) {
exit(33);
}
printf("stegetty on %s\n", strrchr(tty, '/') + 1);
execl("/bin/login", "/bin/login", "--", NULL);
perror("execl");
exit(44);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment