Ini adalah gensio (diucapkan gen'-see-oh), sebuah kerangka kerja untuk memberikan pandangan yang konsisten tentang berbagai tipe I/O aliran (dan paket). Anda membuat objek gensio (atau gensio), dan Anda dapat menggunakan gensio tersebut tanpa harus mengetahui terlalu banyak tentang apa yang terjadi di bawahnya. Anda dapat menumpuk gensio di atas gensio lainnya untuk menambahkan fungsionalitas protokol. Misalnya, Anda dapat membuat gensio TCP, menumpuk SSL di atasnya, dan menumpuk Telnet di atasnya. Mendukung sejumlah jaringan I/O dan port serial. Ini juga mendukung antarmuka suara. gensios yang bertumpuk pada gensios lain disebut filter.
Anda dapat melakukan hal yang sama dengan port penerima. Anda dapat menyiapkan penerima gensio untuk menerima koneksi dalam tumpukan. Jadi dalam contoh kami sebelumnya, Anda dapat mengatur TCP untuk mendengarkan pada port tertentu dan secara otomatis menumpuk SSL dan Telnet di atas ketika koneksi masuk, dan Anda tidak akan diberitahu sampai semuanya siap.
gensio bekerja di Linux, BSD, MacOS, dan Windows. Di Windows, ini memberi Anda antarmuka berbasis peristiwa berkemampuan single-thread (tetapi juga berkemampuan multi-thread) (dengan antarmuka pemblokiran tersedia) untuk menyederhanakan pemrograman dengan banyak I/O. Ini sangat membantu dalam mempermudah penulisan kode berbasis I/O portabel.
Fitur yang sangat penting dari gensio adalah pembuatan koneksi terenkripsi dan terautentikasi jauh lebih mudah dibandingkan tanpa gensio. Di luar manajemen kunci dasar, ini tidak lebih sulit dari TCP atau apa pun. Ini menawarkan fleksibilitas yang diperluas untuk mengendalikan proses otentikasi jika diperlukan. Ini sangat mudah digunakan.
Perhatikan bahwa halaman manual gensio(5) memiliki detail lebih lanjut tentang masing-masing tipe gensio.
Untuk instruksi membangun ini dari sumber, lihat bagian "Membangun" di akhir.
Tersedia beberapa alat yang menggunakan gensios, baik sebagai contoh maupun untuk mencoba sesuatu. Ini adalah:
Daemon mirip sshd yang menggunakan gensios certauth, ssl, dan SCTP atau TCP untuk membuat koneksi. Ini menggunakan otentikasi PAM standar dan menggunakan ptys. Lihat gtlsshd(8) untuk detailnya.
Ada item di FAQ.pertama bernama "Cara menjalankan gtlsshd di Windows", lihat item tersebut dan bagian Membangun di Windows di bawah untuk detail lebih lanjut, karena ada beberapa hal rumit yang harus Anda tangani.
Gensios berikut tersedia di perpustakaan:
Penerima gensio yang menggunakan string tumpukan gensio sebagai parameter. Ini memungkinkan Anda menggunakan gensio sebagai penerima. Ketika conacc dimulai, ia membuka gensio, dan ketika gensio membukanya, ia melaporkan anak baru untuk penerima. Ketika anak menutup, ia mencoba untuk membuka anak itu lagi dan menjalani proses itu lagi (kecuali penerimaan telah dinonaktifkan di conacc).
Mengapa Anda ingin menggunakan ini? Katakanlah di ser2net Anda ingin menghubungkan satu port serial ke port serial lainnya. Anda dapat memiliki koneksi seperti:
connection : &con0
accepter : conacc,serialdev,/dev/ttyS1,115200
connector : serialdev,/dev/ttyS2,115200
Dan itu akan menghubungkan /dev/ttyS1 ke /dev/ttyS2. Tanpa conacc, Anda tidak dapat menggunakan serialdev sebagai penerima. Ini juga memungkinkan Anda menggunakan gtlsshd pada port serial jika Anda ingin login terenkripsi yang diautentikasi melalui port serial. Jika Anda menjalankan gtlsshd dengan yang berikut:
gtlsshd --notcp --nosctp --oneshot --nodaemon --other_acc
' conacc,relpkt(mode=server),msgdelim,/dev/ttyUSB1,115200n81 '
Anda dapat terhubung dengan:
gtlssh --transport ' relpkt,msgdelim,/dev/ttyUSB2,115200n81 ' USB2
Hal ini menciptakan transportasi paket yang dapat diandalkan melalui port serial. Mode=server diperlukan agar relpkt dijalankan sebagai server, karena biasanya dijalankan sebagai klien karena tidak dimulai sebagai penerima. SSL gensio (yang dijalankan melalui transport) memerlukan komunikasi yang andal, sehingga tidak akan dijalankan langsung melalui port serial.
Ya, sepertinya huruf-hurufnya campur aduk.
Filter gensio yang berada di atas gensio suara dan melakukan modem Audio Frequency Shift Keying, seperti yang digunakan pada radio amatir AX.25.
Protokol radio amatir untuk radio paket. Untuk sepenuhnya menggunakan ini, Anda perlu menulis kode, karena kode tersebut menggunakan saluran dan data oob untuk informasi yang tidak bernomor, namun Anda dapat melakukan hal-hal dasar hanya dengan gensiot jika yang Anda perlukan hanyalah satu saluran komunikasi. Misalnya, jika Anda ingin ngobrol dengan seseorang melalui radio, dan port ciuman ada di 8001 di kedua mesin, di mesin penerima Anda dapat menjalankan:
gensiot -i ' stdio(self) ' -a
' ax25(laddr=AE5KM-1),kiss,conacc,tcp,localhost,8001 '
yang akan terhubung ke TNC dan menunggu koneksi di alamat AE5KM-1. Maka Anda bisa menjalankan:
gensiot -i ' stdio(self) '
' ax25(laddr=AE5KM-2,addr="0,AE5KM-1,AE5KM-2"),kiss,tcp,localhost,8001 '
di mesin lain. Ini akan terhubung ke mesin lain melalui TNC 0 dengan alamat yang diberikan. Kemudian apa pun yang Anda ketik di salah satu baris akan muncul di baris lainnya, satu baris demi satu baris. Ketik "Ctrl-D" untuk keluar. Bagian 'stdio(self)' mematikan mode mentah, jadi baris demi baris dan Anda mendapatkan gema lokal. Jika tidak, setiap karakter yang Anda ketik akan mengirimkan paket dan Anda tidak dapat melihat apa yang Anda ketik.
Untuk menghubungkan ke sistem BBS N5COR-11 AX.25, Anda dapat melakukan:
gensiot -i ' xlt(nlcr),stdio(self) '
' ax25(laddr=AE5KM-2,addr="0,N5COR-11,AE5KM-2"),kiss,tcp,localhost,8001 '
Kebanyakan sistem BBS menggunakan CR, bukan NL, untuk baris baru, sehingga xlt gensio digunakan untuk menerjemahkan karakter yang masuk.
Tentu saja, karena gensio ini, Anda dapat meletakkan gensio apa pun yang bisa diterapkan di bawah ax25 yang Anda inginkan. Jadi jika Anda ingin bermain-main atau menguji tanpa radio, Anda bisa melakukan ax25 melalui multicast UDP. Inilah sisi penerima:
gensiot -i ' stdio(self) ' -a
' ax25(laddr=AE5KM-1),conacc, '
' udp(mcast="ipv4,224.0.0.20",laddr="ipv4,1234",nocon), '
' ipv4,224.0.0.20,1234 '
dan inilah sisi konektornya:
gensiot -i ' stdio(self) '
' ax25(laddr=AE5KM-2,addr="0,AE5KM-1,AE5KM-2"), '
' udp(mcast="ipv4,224.0.0.20",laddr="ipv4,1234",nocon), '
' ipv4,224.0.0.20,1234 '
ciuman tidak diperlukan karena UDP sudah menjadi media yang berorientasi paket. Atau Anda dapat menggunakan program greflector untuk membuat simulasi situasi radio. Pada mesin "radiopi2", jalankan:
greflector kiss,tcp,1234
yang akan membuat program yang akan mencerminkan semua masukan yang diterima ke semua koneksi lainnya. Kemudian di sisi penerima:
gensiot -i ' stdio(self) ' -a
' ax25(laddr=AE5KM-1),kiss,conacc,tcp,radiopi2,1234 '
dan sisi penghubung:
gensiot -i ' stdio(self) '
' ax25(laddr=AE5KM-2,addr="0,AE5KM-1,AE5KM-2"),kiss,tcp,radiopi2,1234 '
Kode pengujian menggunakan reflektor untuk beberapa pengujian, karena sangat nyaman digunakan.
Ini semua didokumentasikan secara rinci di gensio(5). Kecuali dinyatakan lain, semua ini tersedia sebagai penerima atau gensios penghubung.
Anda dapat membuat gensios Anda sendiri dan mendaftarkannya ke perpustakaan dan menumpuknya bersama gensios lainnya.
Cara termudah untuk melakukannya adalah dengan mencuri kode dari gensio yang melakukan apa yang Anda inginkan, lalu memodifikasinya untuk membuat gensio Anda sendiri. Sayangnya, tidak ada dokumentasi yang baik tentang cara melakukan hal ini.
File include include/gensio/gensio_class.h memiliki antarmuka antara perpustakaan gensio utama dan gensio. Semua panggilan gensio datang melalui satu fungsi dengan nomor untuk mengidentifikasi fungsi yang diminta. Anda harus memetakan semua ini ke operasi sebenarnya. Ini agak menyakitkan, tetapi membuat kompatibilitas maju dan mundur menjadi lebih mudah.
Membuat gensio Anda sendiri dengan cara ini cukup rumit. Mesin negara untuk hal seperti ini bisa jadi sangat rumit. Pembersihan adalah bagian tersulit. Anda harus memastikan bahwa Anda keluar dari semua panggilan balik dan tidak ada pengatur waktu yang mungkin dipanggil kembali dalam kondisi balapan saat dimatikan. Hanya gensios paling sederhana (echo, dummy), gensios aneh (conadd, keepopen, stdio), dan gensios yang memiliki saluran (mux, ax25) yang langsung mengimplementasikan antarmuka. Yang lainnya menggunakan include/gensio/gensio_base.h. gensio_base menyediakan mesin status dasar untuk gensio. Ia memiliki bagian filter (yang opsional) dan bagian tingkat rendah (ll), yang tidak.
Antarmuka filter menjalankan data untuk diproses. Ini digunakan untuk hal-hal seperti SSL, certauth, ratelimit, dll. Filter gensios akan menggunakan ini. Ini semua menggunakan gensio_ll_gensio (untuk menumpuk gensio di atas gensio lain) untuk ll.
Masing-masing terminal gensios memiliki ll sendiri dan umumnya tidak memiliki filter. Untuk lls berdasarkan deskriptor file (fd), gensio_ll_fd digunakan. Ada juga ll untuk IPMI serial-over-lan (ipmisol) dan untuk suara. Sebagian besar terminal gensios (tcp, udp, sctp, serial port, pty) tentu saja menggunakan fd ll.
Setelah Anda memiliki gensio, Anda dapat mengkompilasinya sebagai modul dan menempelkannya di $(moduleinstalldir)/<version>. Kemudian gensio tinggal mengambilnya dan menggunakannya. Anda juga dapat menghubungkannya dengan aplikasi Anda dan melakukan fungsi init dari aplikasi Anda.
Gensio mdns telah dibahas, tetapi perpustakaan gensio menyediakan antarmuka mDNS yang mudah digunakan. File penyertaannya ada di gensio_mdns.h, dan Anda dapat menggunakan halaman manual gensio_mdns(3) untuk mendapatkan informasi lebih lanjut tentangnya.
Untuk membuat koneksi mdns menggunakan gensiot, misalkan Anda telah menyiapkan ser2net dengan mdns diaktifkan seperti:
connection : &my-port
accepter : telnet(rfc2217),tcp,3001
connector : serialdev,/dev/ttyUSB1,115200N81
options :
mdns : true
maka Anda dapat menghubungkannya dengan gensiot:
gensiot ' mdns,my-port '
gensiot akan menemukan server, port, dan apakah telnet dan rfc2217 diaktifkan dan membuat koneksi.
Selain itu, ada alat gmdns yang memungkinkan Anda melakukan kueri dan periklanan, dan gtlssh dapat melakukan kueri mDNS untuk menemukan layanan. Jika Anda memiliki login aman yang diautentikasi untuk ser2net, dan Anda mengaktifkan mdns di ser2net, seperti:
connection : &access-console
accepter : telnet(rfc2217),mux,certauth(),ssl,tcp,3001
connector : serialdev,/dev/ttyUSBaccess,115200N81
options :
mdns : true
itu membuat pengaturannya menjadi sangat mudah, karena Anda dapat melakukannya:
gtlssh -m access-console
Betul, bisa langsung pakai nama koneksinya saja, tidak perlu tahu hostnya, apakah telnet atau rfc2217 aktif, atau portnya apa. Anda masih harus mengatur kunci dan semacamnya di server ser2net, tentu saja, sesuai instruksi tersebut.
gensio memiliki antarmuka berorientasi objek yang digerakkan oleh peristiwa. Antarmuka sinkron juga tersedia. Anda menangani dua objek utama di gensio: gensio dan penerima gensio. Gensio menyediakan antarmuka komunikasi tempat Anda dapat menghubungkan, memutuskan sambungan, menulis, menerima, dll.
Penerima gensio memungkinkan Anda menerima koneksi masuk. Jika koneksi masuk, itu memberi Anda gensio.
Antarmukanya digerakkan oleh peristiwa karena, sebagian besar, sepenuhnya non-pemblokiran. Jika Anda membuka gensio, Anda memberinya panggilan balik yang akan dipanggil saat koneksi aktif, atau koneksi gagal. Sama untuk jarak dekat. Penulisan akan mengembalikan jumlah byte yang diterima, namun mungkin tidak mengambil semua byte (atau bahkan byte mana pun) dan pemanggil harus memperhitungkannya.
Antarmuka buka dan tutup memiliki antarmuka pemblokiran sekunder untuk kenyamanan. Ini diakhiri dengan _s. Ini untuk kenyamanan, tapi tidak perlu dan penggunaannya harus hati-hati karena Anda tidak bisa menggunakannya dari callback.
Berbicara tentang callback, data dan informasi yang datang dari gensio ke pengguna dilakukan dengan fungsi callback. Membaca data, dan ketika gensio siap untuk menulis, data akan dipanggil kembali. Antarmuka serupa digunakan untuk memanggil dari pengguna ke lapisan gensio, namun disembunyikan dari pengguna. Antarmuka semacam ini mudah diperluas, operasi baru dapat ditambahkan dengan mudah tanpa merusak antarmuka lama.
Library ini menyediakan beberapa cara untuk membuat gensio atau penerima gensio. Cara utamanya adalah str_to_gensio() dan str_to_gensio_accepter(). Ini menyediakan cara untuk menentukan tumpukan gensios atau penerima sebagai string dan build. Secara umum, Anda harus menggunakan antarmuka ini jika Anda bisa.
Secara umum, antarmuka yang tidak sensitif terhadap kinerja didasarkan pada string. Anda akan melihatnya di gensio_control, dan di data tambahan di antarmuka baca dan tulis untuk mengontrol aspek tertentu dari penulisan.
Perpustakaan juga menyediakan cara untuk menyiapkan gensios Anda dengan membuat masing-masing gensios satu per satu. Dalam beberapa situasi, hal ini mungkin diperlukan, namun hal ini membatasi kemampuan untuk menggunakan fitur-fitur baru dari perpustakaan gensio seiring dengan perluasannya.
Jika gensio mendukung banyak aliran (seperti SCTP), nomor aliran diteruskan di auxdata dengan "stream=n". Aliran tidak dikontrol alirannya secara individual.
Saluran, di sisi lain, adalah aliran data terpisah melalui koneksi yang sama. Saluran direpresentasikan sebagai gensios terpisah, dan alirannya dapat dikontrol secara individual.
Ada beberapa file penyertaan yang mungkin perlu Anda tangani saat menggunakan gensios:
Ini sebagian besar didokumentasikan di halaman manual.
Untuk membuat gensios Anda sendiri, file penyertaan berikut tersedia untuk Anda:
Setiap file penyertaan memiliki banyak dokumentasi tentang masing-masing panggilan dan penangannya.
gensio memiliki kumpulan kesalahannya sendiri untuk mengabstraksikannya dari kesalahan OS (bernama GE_xxx) dan memberikan lebih banyak fleksibilitas dalam pelaporan kesalahan. Ini ada dalam file penyertaan gensio_err.h (secara otomatis disertakan dari gensio.h) dan dapat diterjemahkan dari angka ke string yang bermakna dengan gensio_err_to_str(). Nol didefinisikan sebagai bukan kesalahan.
Jika terjadi kesalahan sistem operasi yang tidak dikenal, GE_OSERR dikembalikan dan log dilaporkan melalui antarmuka log pengendali OS.
Satu hal yang sedikit mengganggu tentang gensio adalah Anda harus menyediakan penangan OS (struct gensio_os_funcs) untuk menangani fungsi tipe OS seperti alokasi memori, mutex, kemampuan menangani deskriptor file, pengatur waktu dan waktu, dan beberapa hal lainnya.
Perpustakaan memang menyediakan beberapa penangan OS. Anda dapat memanggil gensio_alloc_os_funcs() untuk mengalokasikan yang default untuk sistem Anda (POSIX atau Windows). Anda dapat melihat halaman manual itu untuk lebih jelasnya. Ini biasanya merupakan opsi dengan kinerja terbaik yang Anda miliki untuk sistem Anda.
Untuk sistem POSIX, tersedia penangan OS untuk glib dan TCL, dialokasikan dengan gensio_glib_funcs_alloc() dan gensio_tcl_funcs_alloc(). Ini sebenarnya tidak berfungsi dengan baik, terutama dari sudut pandang kinerja, API untuk glib dan TCL tidak dirancang dengan baik untuk fungsi gensio. TCL hanya dapat mendukung operasi single-thread. operasi multithread glib hanya memiliki satu thread pada satu waktu menunggu I/O. Tapi mereka berhasil, dan pengujian dijalankan bersama mereka. Ini tidak tersedia di Windows karena abstraksi yang buruk pada glib dan karena kurangnya motivasi pada TCL.
Tetapi jika Anda menggunakan sesuatu yang lain seperti X Windows, dll yang memiliki event loop sendiri, Anda mungkin perlu menyesuaikannya dengan kebutuhan Anda. Namun hal baiknya adalah Anda dapat melakukan ini, dan mengintegrasikan gensio dengan hampir semua hal.
Ada juga antarmuka pelayan yang menyediakan cara mudah untuk menunggu sesuatu terjadi saat menjalankan loop acara. Ini adalah cara umum Anda memasuki perulangan peristiwa, karena ini menyediakan cara mudah untuk memberi sinyal ketika Anda selesai dan harus keluar dari perulangan.
Dokumentasi untuk ini ada di:
termasuk/gensio/gensio_os_funcs.h
Pustaka gensio sepenuhnya mendukung thread dan sepenuhnya aman untuk thread. Namun, ia menggunakan sinyal pada sistem POSIX, dan COM pada sistem Windows, sehingga diperlukan beberapa pengaturan.
Thread "utama" harus memanggil gensio_os_proc_setup() saat startup dan memanggil gensio_os_proc_cleanup() saat selesai. Ini mengatur sinyal dan penangan sinyal, thread penyimpanan lokal di Windows, dan hal-hal lain.
Anda dapat membuat thread baru dari thread yang sudah disiapkan menggunakan gensio_os_new_thread(). Ini memberi Anda thread OS dasar dan dikonfigurasi dengan benar untuk gensio.
Jika Anda memiliki thread yang dibuat dengan cara lain yang ingin Anda gunakan di gensio, selama thread tersebut membuat thread lain dan tidak melakukan fungsi pemblokiran apa pun (penantian apa pun, pemrosesan latar belakang, fungsi yang diakhiri dengan _s seperti read_s, dll.) Anda tidak perlu mengaturnya. Dengan begitu, beberapa thread eksternal dapat menulis data, membangunkan thread lain, atau melakukan hal-hal seperti itu.
Jika thread eksternal perlu melakukan hal tersebut, thread tersebut harus memanggil gensio_os_thread_setup().
Seperti disebutkan di bagian thread, perpustakaan gensio di Unix menggunakan sinyal untuk bangun antar-thread. Saya berusaha keras, dan sebenarnya tidak ada cara lain untuk melakukan ini dengan bersih. Namun Windows juga memiliki beberapa fitur serupa sinyal, dan ini juga tersedia di gensio.
Jika Anda menggunakan gensio_alloc_os_funcs(), Anda akan mendapatkan fungsi OS menggunakan sinyal yang diteruskan untuk IPC. Anda dapat memasukkan GENSIO_OS_FUNCS_DEFAULT_THREAD_SIGNAL untuk sinyalnya jika Anda menginginkan defaultnya, yaitu SIGUSR1. Sinyal yang anda gunakan akan diblokir dan diambil alih oleh gensio, anda tidak dapat menggunakannya.
gensio juga menyediakan beberapa penanganan umum untuk beberapa sinyal. Di Unix, ia akan menangani SIGHUP melalui fungsi gensio_os_proc_register_reload_handler().
Di Windows dan Unix Anda dapat menggunakan gensio_os_proce_register_term_handler(), yang akan menangani permintaan penghentian (SIGINT, SIGTERM, SIGQUIT di Unix) dan gensio_os_proc_register_winsize_handler() (SIGWINCH di Unix). Cara masuknya melalui Windows sedikit lebih berantakan, namun tidak terlihat oleh pengguna.
Semua panggilan balik berasal dari menunggu rutin, bukan dari pengendali sinyal. Itu akan menyederhanakan hidup Anda.
Anda dapat melihat halaman manual untuk rincian lebih lanjut tentang semua ini.
Untuk membuat gensio, cara umum melakukannya adalah dengan memanggil str_to_gensio()
dengan string yang diformat dengan benar. String diformat seperti ini:
<ketik>[([<pilihan>[,<pilihan[...]]])][,<jenis>...][,<pilihan akhir>[,<pilihan akhir>]]
end option
adalah untuk terminal gensios, atau yang berada di bagian bawah tumpukan. Misalnya, tcp,localhost,3001
akan membuat gensio yang terhubung ke port 3001 di localhost. Untuk port serial, contohnya adalah serialdev,/dev/ttyS0,9600N81
akan membuat koneksi ke port serial /dev/ttyS0.
Ini memungkinkan Anda menumpuk lapisan gensio di atas lapisan gensio. Misalnya, untuk melapisi telnet di atas koneksi TCP:
telnet,tcp,localhost,3001
Katakanlah Anda ingin mengaktifkan RFC2217 pada koneksi telnet Anda. Anda dapat menambahkan opsi untuk melakukan itu:
telnet(rfc2217=true),tcp,localhost,3001
Saat Anda membuat gensio, Anda menyediakan callback dengan data pengguna. Ketika peristiwa terjadi pada gensio, callback akan dipanggil sehingga pengguna dapat menanganinya.
Penerima gensio mirip dengan gensio penghubung, namun dengan str_to_gensio_accepter()
sebagai gantinya. Formatnya sama. Misalnya:
telnet(rfc2217=true),tcp,3001
akan membuat penerima TCP dengan telnet di atasnya. Untuk penerima, biasanya Anda tidak perlu menentukan nama host jika ingin mengikat semua antarmuka di mesin lokal.
Setelah Anda membuat gensio, gensio tersebut belum terbuka atau beroperasi. Untuk menggunakannya, Anda harus membukanya. Untuk membukanya, lakukan:
struct gensio * io ;
int rv ;
rv = str_to_gensio ( "tcp,localhost,3001" , oshnd ,
tcpcb , mydata , & io );
if ( rv ) { handle error }
rv = gensio_open ( io , tcp_open_done , mydata );
if ( rv ) { handle error }
Perhatikan bahwa ketika gensio_open()
kembali, gensio tidak terbuka. Anda harus menunggu hingga panggilan balik ( tcp_open_done()
dalam kasus ini) dipanggil. Setelah itu, Anda bisa menggunakannya.
Setelah gensio terbuka, Anda tidak akan langsung mendapatkan data apa pun di dalamnya karena penerimaan dinonaktifkan. Anda harus memanggil gensio_set_read_callback_enable()
untuk menghidupkan dan mematikan apakah callback ( tcpcb
dalam hal ini) akan dipanggil ketika data diterima.
Ketika pengendali baca dipanggil, buffer dan panjangnya diteruskan. Anda tidak harus menangani semua data jika Anda tidak bisa. Anda harus memperbarui buflen dengan jumlah byte yang sebenarnya Anda tangani. Jika Anda tidak menangani data, data yang tidak ditangani akan di-buffer di gensio untuk nanti. Bukan berarti jika tidak menangani semua data, sebaiknya matikan read aktifkan atau event akan langsung terpanggil kembali.
Jika terjadi kesalahan pada koneksi, pengendali baca dipanggil dengan kumpulan kesalahan. buf
dan buflen
akan menjadi NULL dalam kasus ini.
Untuk menulis, Anda dapat memanggil gensio_write()
untuk menulis data. Anda dapat menggunakan gensio_write()
kapan saja di gensio terbuka. gensio_write()
mungkin tidak mengambil semua data yang Anda tulis ke dalamnya. Parameter count
mengembalikan jumlah byte yang sebenarnya diambil dalam panggilan tulis.
Anda dapat merancang kode Anda untuk memanggil gensio_set_write_callback_enable()
ketika Anda memiliki data untuk dikirim dan gensio akan memanggil callback siap tulis dan Anda dapat menulis dari callback tersebut. Ini umumnya lebih sederhana, namun mengaktifkan dan menonaktifkan callback tulis menambah beberapa overhead.
Pendekatan yang lebih efisien adalah dengan menulis data kapan pun Anda membutuhkannya dan menonaktifkan callback tulis. Jika operasi tulis menghasilkan kurang dari permintaan penuh, ujung lainnya memiliki aliran yang terkontrol dan Anda harus mengaktifkan callback tulis dan menunggu hingga dipanggil sebelum mengirim lebih banyak data.
Dalam callback, Anda bisa mendapatkan data pengguna yang Anda masukkan ke panggilan buat dengan gensio_get_user_data()
.
Perhatikan bahwa jika Anda membuka lalu segera menutup gensio, ini tidak masalah, meskipun panggilan balik terbuka belum dipanggil. Callback terbuka mungkin dipanggil atau tidak dalam kasus ini, sehingga mungkin sulit untuk menanganinya dengan benar.
Anda dapat melakukan I/O sinkron dasar dengan gensios. Ini berguna dalam beberapa situasi di mana Anda perlu membaca sesuatu sebaris. Untuk melakukan ini, hubungi:
err = gensio_set_sync ( io );
Gensio yang diberikan akan berhenti mengirimkan acara baca dan tulis. Acara lain disampaikan . Kemudian Anda dapat melakukan:
err = gensio_read_s ( io , & count , data , datalen , & timeout );
err = gensio_write_s ( io , & count , data , datalen , & timeout );
Hitungan diatur ke jumlah aktual byte yang dibaca/ditulis. Mungkin NULL jika Anda tidak peduli (walaupun itu tidak masuk akal untuk dibaca).
Timeout mungkin NULL, jika demikian maka tunggu selamanya. Jika Anda menetapkan batas waktu, batas waktu tersebut akan diperbarui sesuai jumlah waktu yang tersisa.
Perhatikan bahwa sinyal akan menyebabkan sinyal ini segera kembali, namun tidak ada kesalahan yang dilaporkan.
Pembacaan akan diblokir hingga beberapa data masuk dan mengembalikan data tersebut. Itu tidak menunggu sampai buffer penuh. batas waktu adalah jangka waktu, pembacaan akan menunggu jangka waktu tersebut hingga pembacaan selesai dan kembali. Batas waktu bukanlah kesalahan, hitungan hanya akan disetel ke nol.
Menulis blok sampai seluruh buffer ditulis atau terjadi batas waktu. Sekali lagi, batas waktu bukanlah kesalahan, total byte yang sebenarnya ditulis dikembalikan dalam hitungan.
Setelah Anda selesai melakukan I/O sinkron dengan gensio, panggil:
err = gensio_clear_sync ( io );
dan pengiriman melalui antarmuka acara akan berlanjut seperti sebelumnya. Anda tidak boleh berada dalam panggilan baca atau tulis sinkron saat memanggil ini, hasilnya tidak akan ditentukan.
Perhatikan bahwa I/O lain pada gensios lain akan tetap terjadi ketika menunggu I/O sinkron
Saat ini tidak ada cara untuk menunggu beberapa gensios dengan I/O sinkron. Jika Anda melakukan itu, Anda sebaiknya menggunakan I/O berbasis peristiwa saja. Ini lebih efisien, dan pada akhirnya Anda juga melakukan hal yang sama.
Seperti gensio, penerima gensio tidak beroperasi saat Anda membuatnya. Anda harus memanggil gensio_acc_startup()
untuk mengaktifkannya:
struct gensio_accepter * acc ;
int rv ;
rv = str_to_gensio_accepter ( "tcp,3001" , oshnd ,
tcpacccb , mydata , & acc );
if ( rv ) { handle error }
rv = gensio_startup ( acc );
if ( rv ) { handle error }
Perhatikan bahwa tidak ada panggilan balik ke panggilan startup untuk mengetahui kapan panggilan tersebut diaktifkan, karena sebenarnya tidak ada kebutuhan untuk mengetahuinya karena Anda tidak dapat menulis ke panggilan tersebut, ia hanya melakukan panggilan balik.
Bahkan setelah Anda memulai penerima, penerima tetap tidak akan melakukan apa pun sampai Anda memanggil gensio_acc_set_accept_callback_enable()
untuk mengaktifkan panggilan balik tersebut.
Saat panggilan balik dipanggil, ini memberi Anda gensio di parameter data
yang sudah terbuka dengan pembacaan dinonaktifkan. Gensio yang diterima dari akseptor gensio mungkin mempunyai beberapa keterbatasan. Misalnya, Anda mungkin tidak dapat menutup lalu membukanya kembali.
penerima gensio dapat melakukan penerimaan sinkron menggunakan gensio_acc_set_sync()
dan gensio_acc_accept_s
. Lihat halaman manualnya untuk detailnya.
struct gensio_os_funcs
memiliki panggilan balik vlog untuk menangani log gensio internal. Ini dipanggil ketika sesuatu yang penting terjadi namun gensio tidak memiliki cara untuk melaporkan kesalahan. Ini juga dapat digunakan untuk mempermudah mendiagnosis suatu masalah ketika terjadi kesalahan.
Kelas penerima gensio dan gensio masing-masing memiliki subkelas untuk menangani I/O serial dan mengatur semua parameter yang terkait dengan port serial.
Anda dapat mengetahui apakah gensio (atau turunannya) merupakan port serial dengan memanggil gensio_to_sergensio()
. Jika menghasilkan NULL, itu bukan sergensio dan tidak ada turunannya yang merupakan sergensios. Jika ia mengembalikan non-NULL, ia mengembalikan objek sergensio untuk Anda gunakan. Perhatikan bahwa gensio yang dikembalikan oleh sergensio_to_gensio()
akan diteruskan ke gensio_to_sergensio()
, belum tentu gensio yang terkait langsung dengan sergensio.
Sergensio dapat berupa klien, artinya ia dapat mengatur pengaturan serial, atau dapat berupa server, yang berarti ia akan menerima pengaturan serial dari ujung koneksi yang lain.
Kebanyakan sergensios hanya untuk klien: serialdev (port serial normal), ipmisol, dan penerima stdio. Saat ini hanya telnet yang memiliki kemampuan klien dan server.
CATATAN: Antarmuka python yang dijelaskan di sini sudah tidak digunakan lagi. Gunakan yang ada di c++/swig/pygensio sekarang.
Anda dapat mengakses hampir semua antarmuka gensio melalui python, meskipun cara kerjanya sedikit berbeda dari antarmuka C.
Karena python sepenuhnya berorientasi objek, gensios dan gensio akseptor adalah objek kelas satu, bersama dengan gensio_os_funcs, sergensios, dan pelayan.
Ini program kecilnya:
import gensio
class Logger :
def gensio_log ( self , level , log ):
print ( "***%s log: %s" % ( level , log ))
class GHandler :
def __init__ ( self , o , to_write ):
self . to_write = to_write
self . waiter = gensio . waiter ( o )
self . readlen = len ( to_write )
def read_callback ( self , io , err , buf , auxdata ):
if err :
print ( "Got error: " + err )
return 0
print ( "Got data: " + buf );
self . readlen -= len ( buf )
if self . readlen == 0 :
io . read_cb_enable ( False )
self . waiter . wake ()
return len ( buf )
def write_callback ( self , io ):
print ( "Write ready!" )
if self . to_write :
written = io . write ( self . to_write , None )
if ( written >= len ( self . to_write )):
self . to_write = None
io . write_cb_enable ( False )
else :
self . to_write = self . to_write [ written :]
else :
io . write_cb_enable ( False )
def open_done ( self , io , err ):
if err :
print ( "Open error: " + err );
self . waiter . wake ()
else :
print ( "Opened!" )
io . read_cb_enable ( True )
io . write_cb_enable ( True )
def wait ( self ):
self . waiter . wait_timeout ( 1 , 2000 )
o = gensio . alloc_gensio_selector ( Logger ())
h = GHandler ( o , "This is a test" )
g = gensio . gensio ( o , "telnet,tcp,localhost,2002" , h )
g . open ( h )
h . wait ()
Antarmukanya merupakan terjemahan langsung dari antarmuka C. Representasi python dari antarmuka ada di swig/python/gensiodoc.py, Anda dapat melihatnya untuk dokumentasi.
Antarmuka C++ didokumentasikan dalam c++/README.rst.
Antarmuka pygensio yang baru adalah implementasi yang lebih bersih menggunakan swig Director, bukan callback yang dikodekan secara manual ke dalam python. Lihat README.pertama di c++/swig/pygensio. Ada juga glib dan tcl OS_Funcs di direktori glib dan tcl.
Antarmuka C++ lengkap tersedia untuk program Go melalui swig dan swig direksi. Lihat c++/swig/go/README.rst untuk detailnya.
Ini adalah sistem autoconf normal, tidak ada yang istimewa. Perhatikan bahwa jika Anda mendapatkannya langsung dari git, Anda tidak akan menyertakan infrastruktur pembangunan. Ada skrip bernama "reconf" di direktori utama yang akan membuatkannya untuk Anda.
Jika Anda tidak tahu tentang autoconf, file INSTALL memiliki beberapa info, atau cari di Google.
Untuk membangun gensio sepenuhnya, Anda memerlukan hal berikut:
Berikut ini mengatur semuanya kecuali openipmi di ubuntu 20.04:
- sudo apt install gcc g++ git swig python3-dev libssl-dev pkg-config
- libavahi-klien-dev avahi-daemon libtool autoconf automake make libsctp-dev libpam-dev libwrap0-dev libglib2.0-dev tcl-dev libasound2-dev libudev-dev
Di Redhat, libwrap sudah hilang, jadi Anda tidak akan menggunakannya, dan swig tampaknya tidak tersedia, jadi Anda harus membuatnya sendiri dengan setidaknya dukungan go dan python. Berikut perintah untuk sistem mirip Redhat:
- sudo yum install gcc gcc-c++ git python3-devel swig openssl-devel
- PKG-Config Avahi-Devel LIBTOOL AUTOCONF AUTOMAKE Make LKSCTP-TOOLS-Devel-Devel-Devel
Anda mungkin harus melakukan hal berikut untuk memungkinkan akses ke paket pengembangan:
sudo dnf config-manager-set-devel
Dan dapatkan modul kernel SCTP, Anda mungkin harus melakukan:
sudo yum instal kernel-modules-extra
Untuk menggunakan bahasa Go, Anda harus mendapatkan versi Swig 4.1.0 atau lebih besar. Anda mungkin harus menarik versi tepi pendarahan dari git dan menggunakannya.
Menangani konfigurasi instalasi Python sedikit menyakitkan. Secara default, skrip build akan meletakkannya di mana pun program Python mengharapkan program Python yang diinstal. Pengguna normal umumnya tidak memiliki akses menulis ke direktori itu.
Untuk mengesampingkan hal ini, Anda dapat menggunakan opsi konfigurasi-dengan pythoninstall dan-dengan pythoninstalllib atau Anda dapat mengatur variabel lingkungan Pythoninstalldir dan Pythoninstalllibdir ke tempat yang Anda inginkan dan modul pustaka.
Perhatikan bahwa Anda mungkin perlu mengatur-dengan penguncian UUCP ke lockdir Anda (pada sistem yang lebih lama itu/var/kunci, yang merupakan default. Pada yang lebih baru mungkin/run/lock/lockdev. Anda mungkin juga perlu anggota grup dialout dan kunci untuk dapat membuka perangkat serial dan/atau kunci.
Dukungan bahasa GO mengharuskan pergi untuk diinstal dan di jalur.
Ketika saya terus menambahkan gensio ke perpustakaan, seperti crypto, mdns, suara, IPMI, sctp, dll. Jumlah dependensi di perpustakaan semakin lepas kendali. Mengapa Anda harus memuat libasound, atau libopenipmi, jika Anda tidak membutuhkannya? Plus, meskipun perpustakaan didukung menambahkan gensio Anda sendiri melalui API terprogram, ia tidak memiliki cara standar untuk menambahkannya untuk sistem sehingga Anda dapat menulis gensio Anda sendiri dan membiarkan semua orang di sistem menggunakannya.
Perpustakaan Gensio mendukung pemuatan gensio secara dinamis atau membangunnya ke perpustakaan. Secara default jika Anda membuat pustaka bersama, maka semua gensio dikompilasi sebagai modul untuk pemuatan dinamis dan diinstal di tempat yang memungkinkan. Jika Anda tidak membuat perpustakaan bersama, semua gensio dibangun ke dalam perpustakaan. Tetapi Anda dapat mengesampingkan perilaku ini.
Untuk mengatur semua gensio untuk dibangun ke perpustakaan, Anda dapat menambahkan "-dengan semua-gensio = ya" pada baris perintah konfigurasi dan itu akan membangunnya ke perpustakaan.
Anda juga dapat mengaturnya untuk semua dimuat secara dinamis dengan menambahkan "-dengan semua-gensios = dinamis", tetapi ini adalah default.
Anda juga dapat menonaktifkan semua gensio secara default dengan menentukan "-dengan semua-gensios = tidak". Maka tidak ada gensio yang akan dibangun secara default. Ini berguna jika Anda hanya ingin beberapa gensio, Anda dapat mematikan semuanya maka aktifkan maka yang Anda inginkan.
Untuk mengatur bagaimana individu gensio dibangun, Anda lakukan "-dengan <gensio> = x" di mana x adalah "tidak (jangan bangun), ya (dibangun ke perpustakaan) atau dinamis (dieksekusi secara dinamis). Misalnya, Jika Anda hanya ingin membangun TCP Gensio ke dalam perpustakaan dan membuat sisanya dinamis, Anda dapat mengatur untuk semua gensio dinamis dan kemudian menambahkan "--with-net = ya".
Modul -modul ini dimasukkan secara default
Perhatikan bahwa pemuatan dinamis selalu tersedia, bahkan jika Anda membangun semua gensio di perpustakaan. Jadi, Anda masih dapat menambahkan gensio Anda sendiri dengan menambahkan kemudian ke direktori yang tepat.
Gensios akan dimuat terlebih dahulu dari variabel lingkungan LD_LIBRARY_PATH, kemudian dari gensio_library_path, lalu dari lokasi default.
MacOS, menjadi semacam * nix, dibangun cukup bersih dengan homebrew (https://brew.sh). Anda harus, tentu saja, menginstal semua perpustakaan yang Anda butuhkan. Hampir semuanya berfungsi, dengan pengecualian berikut:
* CM108GPIO * sctp * UUCP Locking
Kode DNSSD bawaan digunakan untuk MDN, jadi Avahi tidak diperlukan.
penguncian kawanan untuk port serial berfungsi, jadi penguncian UUCP benar -benar tidak diperlukan.
OpenIpmi harus bekerja, tetapi tidak tersedia di Homebrew sehingga Anda harus membangunnya sendiri.
Instal perangkat lunak yang diperlukan:
- pkg menginstal gcc portaudio autoconf automake libtool mdnsresponder swig
- pergi python3 gmake
Anda harus menggunakan Gmake untuk mengkompilasinya, untuk beberapa alasan Make Standar pada BSD tidak menerima variabel "C ++" dalam daftar persyaratan. Berikut ini tidak berfungsi dan tidak dikompilasi:
* sctp * ipmisol * CM108GPIO
Tambahkan yang berikut ke /etc/rc.conf:
mdnsd_enable = ya
Dan reboot atau memulai layanan.
Pty Gensio gagal oomtest (oomtest 14), tampaknya ada sesuatu dengan BSD PTYS. Saya melihat karakter 07 yang dimasukkan ke dalam aliran data dalam kasus. Saya belum menghabiskan terlalu banyak waktu untuk itu, tetapi karena ini banyak diuji di Linux dan MacOS, saya tidak berpikir masalahnya ada dalam kode Gensio.
Perpustakaan Gensio dapat dibangun di bawah Windows menggunakan Mingw64. Hal -hal berikut tidak berhasil:
* sctp * Pam * libwrap * ipmisol
Anda juga tidak perlu menginstal ALSA, menggunakan antarmuka suara Windows untuk suara.
CM108GPIO menggunakan antarmuka Windows asli, jadi UDEV tidak diperlukan.
Antarmuka Windows built-in MDNS digunakan, jadi Anda tidak perlu Avahi atau DNSSD. Anda perlu menginstal pustaka PCRE jika Anda ingin ekspresi reguler di dalamnya.
Anda perlu mendapatkan msys2 dari https://msys2.org. Kemudian instal AutoConf, Automake, Libtool, Git, Make, dan Swig sebagai alat host:
PACMAN -S AUTOCONF AUTOMAKE LIBTOOL GIT Make Swig
Anda harus menginstal versi MINGW-W64-X86_64-XXX dari semua perpustakaan atau versi MINGW-W64-I686-XXX dari semua perpustakaan. 32-bit tidak diuji dengan baik:
PACMAN -S MINGW-W64-X86_64-GCC mingw-w64-x86_64-python3 mingw-w64-x86_64-pcre MINGW-W64-X86_64-OPENSSL
untuk mingw64, atau untuk UCRT64:
PACMAN -S MINGW-W64-UCRT-X86_64-GCC mingw-w64-ucrt-x86_64-python3 mingw-w64-ucrt-x86_64-pcre MINGW-W64-UCRT-X86_64-OPENSSL
Untuk go, instal pergi dari https://go.dev dan keluar dan masuk kembali. Itu harus berada di jalur, tetapi jika tidak, Anda perlu menambahkannya ke jalur. Saya belum bekerja di Mingw32, tetapi saya belum mencoba versi GO 32-bit.
Untuk gtlsshd, --sysconfdir tidak memiliki arti pada windows. Sebaliknya, Dir Sysconf relatif terhadap tambalan yang dapat dieksekusi, di ../etc/gtlssh. Jadi jika GTLSSHD ada di:
C:/File Program/Gensio/Bin/GTLSSHD
Sysconfdir akan menjadi:
C:/Program File/Gensio/etc/gtlssh
Untuk instalasi standar, Anda dapat menjalankan:
../configure --sbindir =/gensio/bin --libexecdir =/gensio/bin ---bandir =/gensio/man-cludededir =/gensio/include -dengan pythoninstall =/gensio/python3 --prefix =/gensio
Dan ketika Anda menjalankan "Buat instal destdir = ..." dan Anda mengatur destdir ke tempat yang Anda inginkan, seperti "c:/file program". Kemudian Anda dapat menambahkannya ke jalur menggunakan panel kontrol. Untuk menggunakan GTLSSHD, Anda membuat direktori ETC/GTLSSHD di direktori Gensio. Anda harus mengatur izin di direktori ini sehingga hanya sistem dan administrator yang memiliki akses, seperti:
PS C: Program Files (x86) gensio etc> icacls gtlssh GTLSSH NT Authority System: (oi) (CI) (f) Builtin Administrator: (oi) (CI) (f)
Kalau tidak, GTLSSHD akan gagal dengan kesalahan tentang izin pada kunci. Anda dapat mengatur izin ini pada file .key alih -alih direktori, tetapi Anda harus mengaturnya lagi setiap kali Anda menghasilkan kunci baru.
Untuk menggunakan kompiler setup inno, lakukan "buat instal destdir = $ home/install" dan kemudian jalankan Inno di gensio.iss. Ini akan membuat penginstal yang dapat dieksekusi untuk menginstal Gensio.
Maka Anda perlu menghapus file .la dari direktori instal, karena mereka mengacaukan tautan dengan hal -hal lain:
rm $ home/install/gensio/lib/*. la
Ada sejumlah tes untuk gensio. Mereka semua berjalan di Linux jika Anda memiliki modul kernel serialsim. Selain port serial, mereka berjalan di platform lain karena gensio didukung pada platform itu.
Tes port serial memerlukan modul kernel serialsim dan antarmuka python. Ini ada di https://github.com/cminyard/serialsim dan memungkinkan tes menggunakan port serial simulasi untuk membaca garis kontrol modem, menyuntikkan kesalahan, dll.
Anda dapat bertahan tanpa serialsim jika Anda memiliki tiga perangkat serial: satu ketagihan dalam mode echo (rx dan tx diikat bersama -sama) dan dua perangkat serial yang terhubung bersama Do I/O pada satu perangkat pergi ke/berasal dari yang lain. Ini harus bekerja pada platform non-linux. Kemudian atur variabel lingkungan berikut:
export GENSIO_TEST_PIPE_DEVS= " /dev/ttyxxx:/dev/ttywww "
export GENSIO_TEST_ECHO_DEV= " /dev/ttyzzz "
Itu tidak akan dapat menguji ModemState atau RS485.
Mereka juga memerlukan program IPMI_SIM dari perpustakaan OpenIpmi di https://github.com/cminyard/openipmi untuk menjalankan tes IPMISOL.
Untuk menjalankan tes, Anda perlu mengaktifkan beberapa debugging internal untuk mendapatkan efek penuh. Anda biasanya ingin menjalankan sesuatu seperti:
./configure --enable-internal-trace CFLAGS= ' -g -Wall '
Anda dapat menyalakan -O3 di CFLAG juga, jika Anda suka, tetapi itu membuat debugging lebih sulit.
Ada dua jenis tes dasar. Tes Python adalah tes fungsional yang menguji antarmuka Python dan perpustakaan Gensio. Saat ini mereka baik -baik saja, tetapi ada banyak ruang untuk perbaikan. Jika Anda ingin membantu, Anda dapat menulis tes.
Oomtest dulunya adalah penguji memori, tetapi telah berubah menjadi sesuatu yang lebih luas. Ini memunculkan program gensiot dengan variabel lingkungan spesifik untuk menyebabkannya gagal pada titik -titik tertentu, dan melakukan kebocoran memori dan pemeriksaan memori lainnya. Ini menulis data ke gensiot melalui stdin dan menerima data di stdout. Beberapa tes (seperti SerialDev) menggunakan gema. Tes lain membuat koneksi terpisah melalui jaringan dan data mengalir baik ke stdin dan kembali ke koneksi terpisah, dan mengalir ke koneksi terpisah dan kembali melalui stdout. Oomtest adalah multi-threaded dan jumlah utas dapat dikontrol. Oomtest telah menemukan banyak bug. Ini memiliki banyak tombol, tetapi Anda harus melihat kode sumber untuk opsi. Itu perlu didokumentasikan, jika seseorang ingin menjadi sukarelawan ...
Untuk mengatur fuzzing, instal AFL, lalu konfigurasikan dengan yang berikut:
mkdir Zfuzz ; cd Zfuzz
../configure --enable-internal-trace=yes --disable-shared --with-go=no
CC=afl-gcc CXX=afl-g++
Atau gunakan dentang, jika tersedia:
../configure --enable-internal-trace=yes --disable-shared --with-go=no
CC=afl-clang-fast CXX=afl-clang-fast++ LIBS= ' -lstdc++ '
Saya tidak yakin mengapa hal LIBS diperlukan di atas, tetapi saya harus menambahkannya untuk membuatnya dikompilasi.
Lalu bangun. Lalu "Tes CD" dan jalankan "Buat test_fuzz_xxx" di mana xxx adalah salah satu dari: certauth, mux, ssl, telnet, atau relpkt. Anda mungkin perlu menyesuaikan beberapa hal, AFL akan memberi tahu Anda. Perhatikan bahwa itu akan berjalan selamanya, Anda harus ^c setelah Anda selesai.
Makefile dalam tes/makefile.am memiliki instruksi tentang cara menangani kegagalan untuk bereproduksi untuk debugging.
Menjalankan cakupan kode di perpustakaan cukup mudah. Pertama, Anda perlu mengonfigurasi kode untuk mengaktifkan cakupan:
mkdir Ocov ; cd Ocov
../configure --enable-internal-trace=yes
CC= ' gcc -fprofile-arcs -ftest-coverage '
CXX= ' g++ -fprofile-arcs -ftest-coverage '
Kompilasi dan jalankan "buat cek".
Untuk menghasilkan laporan, jalankan:
gcovr -f ' .*/.libs/.* ' -e ' .*python.* '
Ini akan menghasilkan ringkasan. Jika Anda ingin melihat liputan masing -masing baris dalam file, Anda dapat melakukannya:
cd lib
gcov -o .libs/ * .o
Anda dapat melihat file .gcov individu yang dibuat untuk informasi tentang apa yang dibahas. Lihat dokumen GCOV untuk detail.
Pada saat penulisan, saya mendapatkan sekitar 74% cakupan kode, jadi itu sangat bagus. Saya akan bekerja untuk meningkatkannya, sebagian besar melalui peningkatan pengujian fungsional.
Ser2Net digunakan untuk menguji beberapa hal, terutama konfigurasi port serial (Termios dan RFC2217). Anda dapat membangun Ser2Net terhadap versi GCOV dari Gensio Library dan menjalankan "Make Check" di Ser2Net untuk mendapatkan cakupan pada bagian -bagian tersebut. Dengan itu, saya melihat sekitar 76% cakupan, jadi itu tidak menambah total total.
Akan menyenangkan bisa menggabungkan ini dengan fuzzing, tapi saya tidak yakin bagaimana melakukannya. AFL melakukan hal itu sendiri dengan cakupan kode. Tampaknya ada paket AFL-COV yang entah bagaimana mengintegrasikan GCOV, tetapi saya belum melihatnya.