2
2
3
3
VirtualSerialPort::VirtualSerialPort (boost::asio::io_context& io_context, const std::string& device)
4
4
: master_fd_(io_context), device_name_(" /dev/" + device) {
5
+ std::lock_guard<std::mutex> lock (mutex_);
5
6
int master_fd = posix_openpt (O_RDWR | O_NOCTTY);
6
7
if (master_fd == -1 ) {
7
8
BOOST_LOG_TRIVIAL (error) << " Failed to open PTY master: " << strerror (errno);
8
9
throw std::runtime_error (" Failed to open PTY master" );
9
10
}
10
- if (grantpt (master_fd) != 0 || unlockpt (master_fd) != 0 ) {
11
- BOOST_LOG_TRIVIAL (error) << " Failed to grant or unlock PTY: " << strerror (errno);
12
- throw std::runtime_error (" Failed to grant or unlock PTY" );
13
- }
14
-
15
- char * slave_name = ptsname (master_fd);
16
- if (!slave_name) {
17
- BOOST_LOG_TRIVIAL (error) << " Failed to get PTY slave name" ;
18
- throw std::runtime_error (" Failed to get PTY slave name" );
19
- }
20
-
21
- if (unlink (device_name_.c_str ()) == -1 && errno != ENOENT) {
22
- BOOST_LOG_TRIVIAL (error) << " Failed to remove existing symlink: " << strerror (errno);
23
- throw std::runtime_error (" Failed to remove existing symlink" );
24
- }
25
-
26
- if (symlink (slave_name, device_name_.c_str ()) != 0 ) {
27
- BOOST_LOG_TRIVIAL (error) << " Failed to create symlink for PTY slave: " << strerror (errno);
28
- throw std::runtime_error (" Failed to create symlink for PTY slave" );
29
- }
30
-
31
- chmod (device_name_.c_str (), 0660 );
32
- struct group * tty_grp = getgrnam (" tty" );
33
- if (tty_grp && chown (device_name_.c_str (), -1 , tty_grp->gr_gid ) == -1 ) {
34
- BOOST_LOG_TRIVIAL (error) << " Failed to change group of device: " << strerror (errno);
35
- throw std::runtime_error (" Failed to change group of device" );
36
- }
37
-
38
- master_fd_.assign (master_fd);
39
- setup_pty (master_fd);
11
+ BOOST_LOG_TRIVIAL (info) << " PTY master opened successfully" ;
12
+
13
+ if (grantpt (master_fd) != 0 || unlockpt (master_fd) != 0 ) {
14
+ BOOST_LOG_TRIVIAL (error) << " Failed to grant or unlock PTY: " << strerror (errno);
15
+ throw std::runtime_error (" Failed to grant or unlock PTY" );
16
+ }
17
+ BOOST_LOG_TRIVIAL (info) << " PTY grant and unlock successful" ;
18
+
19
+ char * slave_name = ptsname (master_fd);
20
+ if (!slave_name) {
21
+ BOOST_LOG_TRIVIAL (error) << " Failed to get PTY slave name" ;
22
+ throw std::runtime_error (" Failed to get PTY slave name" );
23
+ }
24
+
25
+ if (unlink (device_name_.c_str ()) == -1 && errno != ENOENT) {
26
+ BOOST_LOG_TRIVIAL (error) << " Failed to remove existing symlink: " << strerror (errno);
27
+ throw std::runtime_error (" Failed to remove existing symlink" );
28
+ }
29
+ BOOST_LOG_TRIVIAL (info) << " Existing symlink removed or not present" ;
30
+
31
+ if (symlink (slave_name, device_name_.c_str ()) != 0 ) {
32
+ BOOST_LOG_TRIVIAL (error) << " Failed to create symlink for PTY slave: " << strerror (errno);
33
+ throw std::runtime_error (" Failed to create symlink for PTY slave" );
34
+ }
35
+ BOOST_LOG_TRIVIAL (info) << " Symlink for PTY slave created successfully" ;
36
+
37
+ chmod (device_name_.c_str (), 0660 );
38
+ struct group * tty_grp = getgrnam (" tty" );
39
+ if (tty_grp && chown (device_name_.c_str (), -1 , tty_grp->gr_gid ) == -1 ) {
40
+ BOOST_LOG_TRIVIAL (error) << " Failed to change group of device: " << strerror (errno);
41
+ throw std::runtime_error (" Failed to change group of device" );
42
+ }
43
+ BOOST_LOG_TRIVIAL (info) << " Group changed successfully for the device" ;
44
+
45
+ master_fd_.assign (master_fd);
46
+ setup_pty (master_fd);
40
47
}
41
48
42
49
void VirtualSerialPort::setup_pty (int fd) {
50
+ std::lock_guard<std::mutex> lock (mutex_);
43
51
struct termios tty;
44
52
if (tcgetattr (fd, &tty) != 0 ) {
45
53
BOOST_LOG_TRIVIAL (error) << " Error from tcgetattr: " << strerror (errno);
@@ -61,6 +69,8 @@ void VirtualSerialPort::setup_pty(int fd) {
61
69
62
70
if (tcsetattr (fd, TCSANOW, &tty) != 0 ) {
63
71
BOOST_LOG_TRIVIAL (error) << " Error from tcsetattr: " << strerror (errno);
72
+ } else {
73
+ BOOST_LOG_TRIVIAL (info) << " PTY attributes set successfully" ;
64
74
}
65
75
}
66
76
@@ -74,6 +84,7 @@ VirtualSerialPort::~VirtualSerialPort() {
74
84
}
75
85
76
86
void VirtualSerialPort::async_read (boost::asio::mutable_buffer buffer, std::function<void (const boost::system::error_code&, std::size_t )> handler) {
87
+ std::lock_guard<std::mutex> lock (mutex_);
77
88
BOOST_LOG_TRIVIAL (info) << " VSP::async_read" ;
78
89
boost::asio::async_read (master_fd_, buffer,
79
90
[this , buffer, handler](const boost::system::error_code& ec, std::size_t length) {
@@ -97,6 +108,7 @@ void VirtualSerialPort::async_read(boost::asio::mutable_buffer buffer, std::func
97
108
98
109
99
110
void VirtualSerialPort::async_write (boost::asio::const_buffer buffer, std::function<void (const boost::system::error_code&, std::size_t )> handler) {
111
+ std::lock_guard<std::mutex> lock (mutex_);
100
112
std::string data (boost::asio::buffer_cast<const char *>(buffer), boost::asio::buffer_size (buffer));
101
113
std::stringstream hex_stream;
102
114
hex_stream << std::hex << std::setfill (' 0' );
0 commit comments