feat: implement semaphore locking mechanism for tty devices

This commit is contained in:
fujr 2025-03-14 15:11:34 +08:00
parent db9e257702
commit 02ae2a9603
3 changed files with 78 additions and 0 deletions

View File

@ -157,6 +157,10 @@ int run_op(PROFILE_T *profile,FDS_T *fds)
} }
static void clean_up() static void clean_up()
{ {
if (unlock_at_port(s_profile.tty_dev))
{
err_msg("Failed to unlock tty device");
}
if (tcsetattr(s_fds.tty_fd, TCSANOW, &s_fds.old_termios) != 0) if (tcsetattr(s_fds.tty_fd, TCSANOW, &s_fds.old_termios) != 0)
{ {
err_msg("Error restoring old tty attributes"); err_msg("Error restoring old tty attributes");
@ -174,6 +178,16 @@ int main(int argc, char *argv[])
FDS_T *fds = &s_fds; FDS_T *fds = &s_fds;
parse_user_input(argc, argv, profile); parse_user_input(argc, argv, profile);
dump_profile(); dump_profile();
#ifdef USE_SEMAPHORE
if (profile->tty_dev != NULL)
{
if (lock_at_port(profile->tty_dev))
{
err_msg("Failed to lock tty device");
return COMM_ERROR;
}
}
#endif
// try open tty devices // try open tty devices
if (tty_open_device(profile,fds)) if (tty_open_device(profile,fds))
{ {
@ -184,6 +198,10 @@ int main(int argc, char *argv[])
if (run_op(profile,fds)) if (run_op(profile,fds))
{ {
err_msg("Failed to run operation %d", profile->op); err_msg("Failed to run operation %d", profile->op);
if (unlock_at_port(profile->tty_dev))
{
err_msg("Failed to unlock tty device");
}
kill(getpid(), SIGINT); kill(getpid(), SIGINT);
} }

View File

@ -1,5 +1,48 @@
#include "utils.h" #include "utils.h"
#ifdef USE_SEMAPHORE
void generate_semaphore_name(const char* filename, char* semaphore_name) {
snprintf(semaphore_name, MAX_FILENAME_LEN, "%s%s", SEMAPHORE_PREFIX, filename);
for (int i = 0; semaphore_name[i] != '\0'; i++) {
if (semaphore_name[i] == '/') {
semaphore_name[i] = '_';
}
}
}
int lock_at_port(char* filename){
char semaphore_name[MAX_FILENAME_LEN];
generate_semaphore_name(filename, semaphore_name);
dbg_msg("semaphore_name: %s", semaphore_name);
sem_t *sem = sem_open(semaphore_name, O_CREAT, 0644, 1);
if (sem == SEM_FAILED) {
perror("sem_open failed");
return -1;
}
wait_start = clock();
sem_wait(sem);
dbg_msg("waited %f ms for semaphore", wait_total);
return 0;
}
int unlock_at_port(char* filename){
char semaphore_name[MAX_FILENAME_LEN];
generate_semaphore_name(filename, semaphore_name);
dbg_msg("semaphore_name: %s", semaphore_name);
sem_t *sem = sem_open(semaphore_name, O_CREAT, 0644, 1);
if (sem == SEM_FAILED) {
perror("sem_open failed");
return -1;
}
sem_post(sem);
sem_close(sem);
sem_unlink(semaphore_name);
return 0;
}
#endif
static int char_to_hex(char c) static int char_to_hex(char c)
{ {
// convert char to hex // convert char to hex

View File

@ -1,5 +1,6 @@
#ifndef _UTILS_H #ifndef _UTILS_H
#define _UTILS_H #define _UTILS_H
#define USE_SEMAPHORE 1
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
@ -13,6 +14,22 @@
#include "extlib/pdu.h" #include "extlib/pdu.h"
#include "time.h" #include "time.h"
#ifdef USE_SEMAPHORE
#include <semaphore.h>
#include <sys/wait.h>
#include <sys/types.h>
#define MAX_FILENAME_LEN 256
#define SEMAPHORE_PREFIX "tom_modem_lock"
typedef struct FileLock {
char filename[MAX_FILENAME_LEN];
sem_t semaphore;
} FileLock;
void generate_semaphore_name(const char* filename, char* semaphore_name);
int lock_at_port(char* filename);
int unlock_at_port(char* filename);
#endif
extern PROFILE_T s_profile; extern PROFILE_T s_profile;
extern FDS_T s_fds; extern FDS_T s_fds;