이는 다양한 스트림(및 패킷) I/O 유형에 대한 일관된 보기를 제공하기 위한 프레임워크인 gensio(gen'-see-oh로 발음)입니다. gensio 객체(또는 gensio)를 생성하면 그 아래에서 무슨 일이 일어나고 있는지 너무 많이 알 필요 없이 해당 gensio를 사용할 수 있습니다. gensio를 다른 것 위에 쌓아 프로토콜 기능을 추가할 수 있습니다. 예를 들어 TCP gensio를 생성하고 그 위에 SSL을 쌓고 그 위에 Telnet을 쌓을 수 있습니다. 다수의 네트워크 I/O 및 직렬 포트를 지원합니다. 사운드 인터페이스도 지원합니다. 다른 gensio 위에 쌓이는 gensio를 필터라고 합니다.
수신 포트에서도 동일한 작업을 수행할 수 있습니다. 스택의 연결을 허용하도록 gensio 수용체를 설정할 수 있습니다. 따라서 이전 예에서는 특정 포트에서 수신 대기하도록 TCP를 설정하고 연결이 들어올 때 SSL과 Telnet을 자동으로 위에 스택할 수 있으며 모든 것이 준비될 때까지 알림을 받지 못합니다.
gensio는 Linux, BSD, MacOS 및 Windows에서 작동합니다. Windows에서는 많은 I/O로 프로그래밍을 단순화하기 위해 단일 스레드 가능(그러나 다중 스레드 가능) 이벤트 기반 인터페이스(차단 인터페이스 사용 가능)를 제공합니다. 이식 가능한 I/O 기반 코드를 쉽게 작성하는 데 큰 도움이 됩니다.
gensio의 매우 중요한 기능은 gensio가 없을 때보다 암호화되고 인증된 연결을 훨씬 쉽게 설정할 수 있다는 것입니다. 기본 키 관리 외에는 실제로 TCP나 다른 것보다 어렵지 않습니다. 필요한 경우 인증 프로세스를 제어하기 위한 확장된 유연성을 제공합니다. 사용하기가 정말 쉽습니다.
gensio(5) 매뉴얼 페이지에는 개별 gensio 유형에 대한 자세한 내용이 있습니다.
소스에서 이를 빌드하는 방법에 대한 지침은 끝에 있는 "빌딩" 섹션을 참조하세요.
gensios를 예제로 사용하고 시험해 볼 수 있는 몇 가지 도구를 사용할 수 있습니다. 이것들은 다음과 같습니다:
연결을 위해 certauth, ssl, SCTP 또는 TCP gensios를 사용하는 sshd와 유사한 데몬입니다. 표준 PAM 인증을 사용하고 ptys를 사용합니다. 자세한 내용은 gtlsshd(8)를 참조하세요.
FAQ.rst에는 "Windows에서 gtlsshd를 실행하는 방법"이라는 항목이 있습니다. 처리해야 할 몇 가지 까다로운 작업이 있으므로 자세한 내용은 해당 항목과 아래 Windows에서 빌드 섹션을 참조하세요.
라이브러리에서 다음 gensio를 사용할 수 있습니다.
gensio 스택 문자열을 매개변수로 사용하는 gensio 수용체입니다. 이를 통해 gensio를 수용체로 사용할 수 있습니다. conacc가 시작되면 gensio가 열리고 gensio가 열리면 수락자에 대한 새 하위 항목이 보고됩니다. 자식이 닫히면 자식을 다시 열고 프로세스를 다시 진행하려고 시도합니다(conacc에서 수락이 비활성화되지 않은 경우).
왜 이것을 사용하고 싶습니까? ser2net에서 하나의 직렬 포트를 다른 직렬 포트에 연결하고 싶다고 가정해 보겠습니다. 다음과 같은 연결이 있을 수 있습니다.
connection : &con0
accepter : conacc,serialdev,/dev/ttyS1,115200
connector : serialdev,/dev/ttyS2,115200
그리고 /dev/ttyS1을 /dev/ttyS2에 연결합니다. conacc가 없으면 serialdev를 수락자로 사용할 수 없습니다. 또한 직렬 포트를 통해 암호화된 인증 로그인을 원하는 경우 직렬 포트에서 gtlsshd를 사용할 수 있습니다. 다음과 같이 gtlsshd를 실행한 경우:
gtlsshd --notcp --nosctp --oneshot --nodaemon --other_acc
' conacc,relpkt(mode=server),msgdelim,/dev/ttyUSB1,115200n81 '
다음과 같이 연결할 수 있습니다.
gtlssh --transport ' relpkt,msgdelim,/dev/ttyUSB2,115200n81 ' USB2
이는 직렬 포트를 통한 안정적인 패킷 전송을 생성합니다. relpkt가 서버로 실행되도록 하려면 mode=server가 필요합니다. 왜냐하면 relpkt는 승인자로 시작되지 않기 때문에 일반적으로 클라이언트로 실행되기 때문입니다. SSL gensio(전송을 통해 실행됨)에는 안정적인 통신이 필요하므로 직렬 포트를 통해 직접 실행되지 않습니다.
네, 글자가 뒤죽박죽된 것 같습니다.
사운드 젠시오 위에 위치하며 AX.25 아마추어 라디오에 사용되는 것과 같은 오디오 주파수 편이 변조 모뎀을 수행하는 필터 젠시오입니다.
패킷 라디오용 아마추어 라디오 프로토콜입니다. 이를 완전히 사용하려면 번호가 없는 정보에 대해 채널과 oob 데이터를 사용하므로 코드를 작성해야 하지만 필요한 것이 하나의 통신 채널뿐이라면 gensiot만으로 기본적인 작업을 수행할 수 있습니다. 예를 들어, 라디오를 통해 누군가와 채팅하고 싶고 키스 포트가 두 컴퓨터 모두 8001에 있는 경우 수락하는 컴퓨터에서 다음을 실행할 수 있습니다.
gensiot -i ' stdio(self) ' -a
' ax25(laddr=AE5KM-1),kiss,conacc,tcp,localhost,8001 '
이는 TNC에 연결되고 주소 AE5KM-1에서 연결을 기다립니다. 그런 다음 다음을 실행할 수 있습니다.
gensiot -i ' stdio(self) '
' ax25(laddr=AE5KM-2,addr="0,AE5KM-1,AE5KM-2"),kiss,tcp,localhost,8001 '
다른 기계에서. 그러면 주어진 주소를 사용하여 TNC 0을 통해 다른 시스템에 연결됩니다. 그러면 한 항목에 입력한 내용이 다른 항목에 한 번에 한 줄씩 표시됩니다. 종료하려면 "Ctrl-D"를 입력하세요. 'stdio(self)' 부분은 원시 모드를 끄므로 한 번에 한 줄씩 로컬 에코가 발생합니다. 그렇지 않으면 귀하가 입력하는 모든 문자가 패킷을 보내어 귀하가 입력하는 내용을 볼 수 없게 됩니다.
N5COR-11 AX.25 BBS 시스템에 연결하려면 다음을 수행합니다.
gensiot -i ' xlt(nlcr),stdio(self) '
' ax25(laddr=AE5KM-2,addr="0,N5COR-11,AE5KM-2"),kiss,tcp,localhost,8001 '
대부분의 BBS 시스템은 새 줄에 NL이 아닌 CR을 사용하므로 xlt gensio는 들어오는 이러한 문자를 번역하는 데 사용됩니다.
물론, 이것은 gensio이기 때문에 원하는 대로 ax25 아래에 실행 가능한 gensio를 둘 수 있습니다. 따라서 라디오 없이 실험하거나 테스트하려면 UDP 멀티캐스트를 통해 ax25를 수행할 수 있습니다. 수락자 쪽은 다음과 같습니다.
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 '
커넥터 쪽은 다음과 같습니다.
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 '
UDP는 이미 패킷 지향 미디어이므로 키스가 필요하지 않습니다. 또는 반사경 프로그램을 사용하여 시뮬레이션된 무선 상황을 만들 수 있습니다. "radiopi2" 머신에서 다음을 실행합니다.
greflector kiss,tcp,1234
그러면 수신된 모든 입력을 다른 모든 연결에 반영하는 프로그램이 생성됩니다. 그런 다음 수락자 측에서 다음을 수행합니다.
gensiot -i ' stdio(self) ' -a
' ax25(laddr=AE5KM-1),kiss,conacc,tcp,radiopi2,1234 '
그리고 연결하는 쪽:
gensiot -i ' stdio(self) '
' ax25(laddr=AE5KM-2,addr="0,AE5KM-1,AE5KM-2"),kiss,tcp,radiopi2,1234 '
테스트 코드에서는 사용하기 매우 편리하기 때문에 일부 테스트에 리플렉터를 사용합니다.
이것들은 모두 gensio(5)에 자세히 문서화되어 있습니다. 달리 명시하지 않는 한, 이들 모두는 수용체 또는 연결 젠시오로 사용할 수 있습니다.
자신만의 젠시오를 생성하여 라이브러리에 등록하고 다른 젠시오와 함께 쌓을 수 있습니다.
이를 수행하는 가장 쉬운 방법은 원하는 작업을 수행하는 gensio에서 코드를 훔친 다음 수정하여 자신만의 gensio를 만드는 것입니다. 불행히도 이 작업을 수행하는 방법에 대한 좋은 문서가 없습니다.
포함 파일 include/gensio/gensio_class.h에는 기본 gensio 라이브러리와 gensio 간의 인터페이스가 있습니다. gensio 호출은 모두 요청되는 기능을 식별하기 위한 숫자가 포함된 단일 기능을 통해 이루어집니다. 이 모든 것을 실제 작업에 매핑해야 합니다. 이는 다소 고통스럽기는 하지만 상위 및 하위 호환성을 훨씬 쉽게 만듭니다.
이런 방식으로 자신만의 gensio를 만드는 것은 상당히 복잡합니다. 이와 같은 상태 머신은 놀라울 정도로 복잡할 수 있습니다. 청소가 가장 어려운 부분입니다. 모든 콜백이 종료되었는지 확인해야 하며 종료 시 경쟁 조건으로 인해 타이머가 다시 콜백되지 않을 수도 있습니다. 가장 단순한 gensios(echo, dummy), 이상한 gensios(conadd, keepopen, stdio) 및 채널이 있는 gensios(mux, ax25)만이 인터페이스를 직접 구현합니다. 다른 모든 것은 include/gensio/gensio_base.h를 사용합니다. gensio_base는 gensio에 대한 기본 상태 머신을 제공합니다. 필터 부분(선택 사항)과 하위 수준(II) 부분이 있지만 그렇지 않습니다.
필터 인터페이스에는 처리를 위해 실행되는 데이터가 있습니다. 이것은 ssl, certauth, ratelimit 등과 같은 것에 사용됩니다. Filter gensios는 이것을 사용합니다. 이들은 모두 ll에 대해 gensio_ll_gensio(다른 gensio 위에 gensio를 쌓는 데 사용)를 사용합니다.
터미널 젠시오에는 각각 고유한 ll이 있으며 일반적으로 필터가 없습니다. 파일 설명자(fd)를 기반으로 하는 ll의 경우 gensio_ll_fd가 사용됩니다. IPMI serial-over-lan(ipmisol) 및 사운드에 대한 ll도 있습니다. 대부분의 터미널 gensios(tcp, udp, sctp, 직렬 포트, pty)는 당연히 fd ll을 사용합니다.
gensio가 있으면 이를 모듈로 컴파일하고 $(moduleinstalldir)/<version>에 붙일 수 있습니다. 그러면 젠시오가 그냥 골라서 사용하게 됩니다. 또한 이를 애플리케이션과 연결하고 애플리케이션에서 초기화 기능을 수행할 수도 있습니다.
mdns gensio는 이미 논의되었지만 gensio 라이브러리는 사용하기 쉬운 mDNS 인터페이스를 제공합니다. 이에 대한 포함 파일은 gensio_mdns.h에 있으며 gensio_mdns(3) 매뉴얼 페이지를 사용하여 이에 대한 자세한 정보를 얻을 수 있습니다.
gensiot를 사용하여 mdns 연결을 만들려면 다음과 같이 mdns가 활성화된 ser2net을 설정해야 합니다.
connection : &my-port
accepter : telnet(rfc2217),tcp,3001
connector : serialdev,/dev/ttyUSB1,115200N81
options :
mdns : true
그런 다음 gensiot를 사용하여 연결할 수 있습니다.
gensiot ' mdns,my-port '
gensiot는 서버, 포트, telnet 및 rfc2217 활성화 여부를 찾아 연결합니다.
또한 쿼리와 광고를 수행할 수 있는 gmdns 도구가 있으며, gtlssh는 mDNS 쿼리를 수행하여 서비스를 찾을 수 있습니다. ser2net에 대한 보안 인증 로그인이 있고 다음과 같이 ser2net에서 mdns를 활성화하는 경우:
connection : &access-console
accepter : telnet(rfc2217),mux,certauth(),ssl,tcp,3001
connector : serialdev,/dev/ttyUSBaccess,115200N81
options :
mdns : true
이렇게 하면 설정이 매우 편리해집니다. 다음과 같이 할 수 있습니다.
gtlssh -m access-console
맞습니다. 호스트를 알 필요 없이 연결 이름만 직접 사용할 수 있습니다. 텔넷이나 rfc2217이 활성화되어 있는지 또는 포트가 무엇인지 알 필요가 없습니다. 물론 해당 지침에 따라 ser2net 서버에 키 등을 설정해야 합니다.
gensio에는 이벤트 중심의 객체 지향 인터페이스가 있습니다. 동기식 인터페이스도 사용할 수 있습니다. gensio에서는 gensio와 gensio accepter라는 두 가지 주요 객체를 다룹니다. gensio는 연결, 연결 해제, 쓰기, 수신 등이 가능한 통신 인터페이스를 제공합니다.
gensio Accepter를 사용하면 들어오는 연결을 수신할 수 있습니다. 연결이 들어오면 gensio가 제공됩니다.
인터페이스는 대부분 완전히 비차단형이기 때문에 이벤트 기반입니다. gensio를 열면 연결이 설정되거나 연결이 실패할 때 호출되는 콜백을 제공합니다. 닫기에도 마찬가지입니다. 쓰기는 허용된 바이트 수를 반환하지만 모든 바이트(또는 심지어 일부 바이트)도 사용하지 않을 수 있으므로 호출자는 이를 고려해야 합니다.
개방형 및 폐쇄형 인터페이스에는 편의를 위해 보조 차단 인터페이스가 있습니다. _s로 끝납니다. 이는 편의를 위한 것이지만 반드시 필요한 것은 아니며 콜백에서 실제로 사용할 수 없기 때문에 주의해서 사용해야 합니다.
콜백에 관해 말하자면, gensio에서 사용자에게 전달되는 데이터와 정보는 함수 콜백을 통해 수행됩니다. 데이터를 읽고, gensio가 데이터 쓰기 준비가 되면 콜백으로 다시 돌아옵니다. 사용자가 gensio 레이어를 호출하는 데 유사한 인터페이스가 사용되지만 사용자에게는 숨겨져 있습니다. 이러한 종류의 인터페이스는 쉽게 확장 가능하며 기존 인터페이스를 손상시키지 않고도 새로운 작업을 쉽게 추가할 수 있습니다.
라이브러리는 gensio 또는 gensio 수용체를 생성하는 여러 가지 방법을 제공합니다. 주요 방법은 str_to_gensio() 및 str_to_gensio_accepter()입니다. 이는 gensios 또는 accepters 스택을 문자열로 지정하고 빌드하는 방법을 제공합니다. 일반적으로 가능하다면 이 인터페이스를 사용해야 합니다.
일반적으로 성능에 민감하지 않은 인터페이스는 문자열 기반입니다. gensio_control과 읽기 및 쓰기 인터페이스의 보조 데이터에서 이를 확인하여 쓰기의 특정 측면을 제어할 수 있습니다.
라이브러리는 또한 각각을 개별적으로 생성하여 gensio를 설정하는 방법을 제공합니다. 상황에 따라 이것이 필요할 수도 있지만 확장됨에 따라 gensio 라이브러리의 새로운 기능을 사용하는 기능이 제한됩니다.
gensio가 SCTP와 같은 여러 스트림을 지원하는 경우 스트림 번호는 "stream=n"을 사용하여 auxdata에 전달됩니다. 스트림은 개별적으로 흐름을 제어하지 않습니다.
반면에 채널은 동일한 연결을 통한 별도의 데이터 흐름입니다. 채널은 별도의 젠시오로 표시되며 개별적으로 흐름을 제어할 수 있습니다.
gensios를 사용할 때 처리해야 할 몇 가지 포함 파일이 있습니다.
이러한 내용은 대부분 매뉴얼 페이지에 문서화되어 있습니다.
자신만의 gensio를 생성하려면 다음 포함 파일을 사용할 수 있습니다.
각 포함 파일에는 개별 호출 및 처리기에 대한 많은 문서가 있습니다.
gensio에는 OS 오류(GE_xxx라는 이름)에서 이를 추상화하고 오류 보고에 더 많은 유연성을 제공하는 자체 오류 세트가 있습니다. 이는 gensio_err.h 포함 파일(gensio.h에서 자동으로 포함됨)에 있으며 gensio_err_to_str()을 사용하여 숫자를 의미 있는 문자열로 변환할 수 있습니다. 0은 오류가 아닌 것으로 정의됩니다.
인식할 수 없는 운영 체제 오류가 발생하면 GE_OSERR이 반환되고 OS 핸들러 로그 인터페이스를 통해 로그가 보고됩니다.
gensio에 대해 약간 짜증나는 점 중 하나는 메모리 할당, 뮤텍스, 파일 설명자, 타이머 및 시간을 처리하는 기능 및 기타 몇 가지 기능과 같은 OS 유형 기능을 처리하기 위해 OS 핸들러(struct gensio_os_funcs)를 제공해야 한다는 것입니다.
라이브러리는 여러 OS 핸들러를 제공합니다. gensio_alloc_os_funcs()를 호출하여 시스템(POSIX 또는 Windows)에 대한 기본 값을 할당할 수 있습니다. 자세한 내용은 해당 매뉴얼 페이지를 참조하세요. 이는 일반적으로 시스템에 대해 가장 성능이 좋은 옵션입니다.
POSIX 시스템의 경우 glib 및 TCL용 OS 핸들러를 사용할 수 있으며 gensio_glib_funcs_alloc() 및 gensio_tcl_funcs_alloc()을 통해 할당됩니다. 특히 성능 관점에서 볼 때 이는 실제로 잘 작동하지 않습니다. glib 및 TCL용 API는 gensio의 기능에 맞게 잘 설계되지 않았습니다. TCL은 단일 스레드 작업만 지원할 수 있습니다. glib 다중 스레드 작업에는 I/O를 기다리는 한 번에 하나의 스레드만 있습니다. 그러나 그들은 작동하고 테스트도 함께 실행됩니다. glib의 추상화가 좋지 않고 TCL에 대한 동기가 부족하기 때문에 Windows에서는 이러한 기능을 사용할 수 없습니다.
그러나 자체 이벤트 루프가 있는 X Windows 등과 같은 다른 것을 사용하는 경우 필요에 맞게 조정해야 할 수도 있습니다. 그러나 좋은 점은 이를 수행할 수 있고 gensio를 거의 모든 것과 통합할 수 있다는 것입니다.
이벤트 루프를 실행하는 동안 어떤 일이 발생할 때까지 기다리는 편리한 방법을 제공하는 웨이터 인터페이스도 있습니다. 이는 작업이 완료되어 루프를 종료해야 할 때 신호를 보내는 편리한 방법을 제공하기 때문에 일반적으로 이벤트 루프에 들어가는 방법입니다.
이에 대한 문서는 다음 위치에 있습니다.
include/gensio/gensio_os_funcs.h
gensio 라이브러리는 스레드를 완벽하게 지원하며 완전히 스레드로부터 안전합니다. 그러나 POSIX 시스템에서는 신호를 사용하고 Windows 시스템에서는 COM을 사용하므로 일부 설정이 필요합니다.
"기본" 스레드는 시작 시 gensio_os_proc_setup()을 호출하고 완료되면 gensio_os_proc_cleanup()을 호출해야 합니다. 이는 신호 및 신호 처리기, Windows의 스레드 로컬 저장소 및 기타 종류의 항목을 설정합니다.
gensio_os_new_thread()를 사용하여 이미 설정된 스레드에서 새 스레드를 생성할 수 있습니다. 이는 기본 OS 스레드를 제공하며 gensio에 맞게 구성됩니다.
gensio에서 사용하려는 다른 방법으로 생성된 스레드가 있는 경우 스레드가 다른 스레드를 생성하고 차단 기능(모든 종류의 대기, 백그라운드 처리, read_s와 같이 _s로 끝나는 함수, 등) 설정할 필요가 없습니다. 이렇게 하면 일부 외부 스레드가 데이터를 쓰거나 다른 스레드를 깨우거나 이와 유사한 작업을 수행할 수 있습니다.
외부 스레드가 이러한 작업을 수행해야 하는 경우 gensio_os_thread_setup()을 호출해야 합니다.
스레드 섹션에서 언급했듯이 Unix의 gensio 라이브러리는 스레드 간 깨우기에 신호를 사용합니다. 열심히 찾아봤는데 정말 깔끔하게 할 수 있는 다른 방법이 없네요. 하지만 Windows에는 몇 가지 신호와 유사한 기능도 있으며 gensio에서도 사용할 수 있습니다.
gensio_alloc_os_funcs()를 사용하면 IPC에 대해 전달된 신호를 사용하여 OS funcs를 얻게 됩니다. 기본값인 SIGUSR1을 원하는 경우 신호에 대해 GENSIO_OS_FUNCS_DEFAULT_THREAD_SIGNAL을 전달할 수 있습니다. 귀하가 사용하는 신호는 gensio에 의해 차단되고 인계되므로 사용할 수 없습니다.
gensio는 또한 몇 가지 신호에 대한 몇 가지 일반적인 처리 기능을 제공합니다. Unix에서는 gensio_os_proc_register_reload_handler() 함수를 통해 SIGHUP을 처리합니다.
Windows 및 Unix에서는 종료 요청(Unix의 SIGINT, SIGTERM, SIGQUIT) 및 gensio_os_proc_register_winsize_handler()(Unix의 SIGWINCH)를 처리하는 gensio_os_proce_register_term_handler()를 사용할 수 있습니다. Windows를 통해 이러한 정보가 들어오는 방식은 조금 더 복잡하지만 사용자에게는 보이지 않습니다.
신호 핸들러가 아닌 대기 루틴의 대기에서 발생한 모든 콜백입니다. 그것은 당신의 삶을 훨씬 단순화시킬 것입니다.
이들 모두에 대한 자세한 내용은 매뉴얼 페이지를 참조하세요.
gensio를 생성하기 위한 일반적인 방법은 올바른 형식의 문자열을 사용하여 str_to_gensio()
호출하는 것입니다. 문자열은 다음과 같이 형식화됩니다.
<유형>[([<옵션>[,<옵션[...]]])][,<유형>...][,<종료 옵션>[,<종료 옵션>]]
end option
은 터미널 gensios 또는 스택 맨 아래에 있는 gensios용입니다. 예를 들어, tcp,localhost,3001
localhost의 포트 3001에 연결하는 gensio를 생성합니다. 직렬 포트의 경우 예를 들면 serialdev,/dev/ttyS0,9600N81
직렬 포트 /dev/ttyS0에 대한 연결을 생성합니다.
이를 통해 gensio 레이어 위에 gensio 레이어를 쌓을 수 있습니다. 예를 들어, TCP 연결 위에 텔넷을 계층화하려면 다음을 수행하십시오.
telnet,tcp,localhost,3001
텔넷 연결에서 RFC2217을 활성화하고 싶다고 가정해 보겠습니다. 이를 수행하는 옵션을 추가할 수 있습니다.
telnet(rfc2217=true),tcp,localhost,3001
gensio를 생성할 때 사용자 데이터와 함께 콜백을 제공합니다. gensio에서 이벤트가 발생하면 사용자가 이를 처리할 수 있도록 콜백이 호출됩니다.
gensio 수락자는 연결 gensio와 유사하지만 대신 str_to_gensio_accepter()
사용합니다. 형식은 동일합니다. 예를 들어:
telnet(rfc2217=true),tcp,3001
맨 위에 텔넷이 있는 TCP 수락자를 생성합니다. 수락자의 경우 로컬 시스템의 모든 인터페이스에 바인딩하려는 경우 일반적으로 호스트 이름을 지정할 필요가 없습니다.
gensio를 생성한 후에는 아직 열리지 않거나 작동되지 않습니다. 사용하려면 열어야 합니다. 열려면 다음을 수행하십시오.
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 }
gensio_open()
반환될 때 gensio는 열려 있지 않습니다. 콜백(이 경우 tcp_open_done()
)이 호출될 때까지 기다려야 합니다. 그 후에는 사용할 수 있습니다.
gensio가 열리면 수신이 꺼지기 때문에 데이터를 즉시 얻을 수 없습니다. 데이터 수신 시 콜백(이 경우 tcpcb
) 호출 여부를 켜고 끄려면 gensio_set_read_callback_enable()
호출해야 합니다.
읽기 핸들러가 호출되면 버퍼와 길이가 전달됩니다. 처리할 수 없는 경우 모든 데이터를 처리할 필요는 없습니다. 실제로 처리한 바이트 수로 buflen을 업데이트 해야 합니다 . 데이터를 처리하지 않으면 처리되지 않은 데이터는 나중에 사용할 수 있도록 gensio에 버퍼링됩니다. 모든 데이터를 처리하지 못한다면 읽기 활성화를 꺼야 합니다. 그렇지 않으면 이벤트가 즉시 다시 호출됩니다.
연결에 문제가 발생하면 오류 세트와 함께 읽기 핸들러가 호출됩니다. 이 경우 buf
및 buflen
NULL이 됩니다.
쓰기의 경우 gensio_write()
호출하여 데이터를 쓸 수 있습니다. 열려 있는 gensio에서 언제든지 gensio_write()
사용할 수 있습니다. gensio_write()
작성한 모든 데이터를 가져오지 못할 수도 있습니다. count
매개변수는 쓰기 호출에서 실제로 사용된 바이트 수를 다시 전달합니다.
보낼 데이터가 있을 때 gensio_set_write_callback_enable()
호출하도록 코드를 설계할 수 있으며 gensio는 쓰기 준비 콜백을 호출하고 콜백에서 쓸 수 있습니다. 이는 일반적으로 더 간단하지만 쓰기 콜백을 활성화 및 비활성화하면 약간의 오버헤드가 추가됩니다.
보다 효율적인 접근 방식은 필요할 때마다 데이터를 쓰고 쓰기 콜백을 비활성화하는 것입니다. 쓰기 작업이 전체 요청보다 적은 양을 반환하는 경우 다른 쪽 끝은 흐름 제어를 갖고 있으므로 쓰기 콜백을 활성화하고 호출될 때까지 기다려야 더 많은 데이터를 보낼 수 있습니다.
콜백에서 gensio_get_user_data()
사용하여 생성 호출에 전달한 사용자 데이터를 가져올 수 있습니다.
gensio를 연 다음 즉시 닫는 경우에는 열기 콜백이 호출되지 않았더라도 괜찮습니다. 하지만 이 경우 공개 콜백이 호출될 수도 있고 호출되지 않을 수도 있으므로 이를 적절하게 처리하기 어려울 수 있습니다.
gensios를 사용하면 기본적인 동기 I/O를 수행할 수 있습니다. 이는 인라인으로 읽어야 하는 일부 상황에서 유용합니다. 이렇게 하려면 다음을 호출하세요.
err = gensio_set_sync ( io );
해당 gensio는 읽기 및 쓰기 이벤트 전달을 중단합니다. 기타 이벤트가 전달 됩니다 . 그러면 다음을 수행할 수 있습니다.
err = gensio_read_s ( io , & count , data , datalen , & timeout );
err = gensio_write_s ( io , & count , data , datalen , & timeout );
Count는 읽거나 쓴 실제 바이트 수로 설정됩니다. 상관하지 않으면 NULL이 될 수 있습니다(읽을 때는 별 의미가 없지만).
시간 초과는 NULL일 수 있습니다. 그렇다면 영원히 기다리십시오. 제한 시간을 설정하면 남은 시간만큼 업데이트됩니다.
신호로 인해 즉시 반환되지만 오류는 보고되지 않습니다.
일부 데이터가 들어와 해당 데이터를 반환할 때까지 읽기가 차단됩니다. 버퍼가 가득 찰 때까지 기다리지 않습니다. timeout은 timeval이며, 읽기는 읽기가 완료되고 반환될 때까지 해당 시간 동안 기다립니다. 시간 초과는 오류가 아니며 개수는 0으로 설정됩니다.
전체 버퍼가 기록되거나 시간 초과가 발생할 때까지 블록을 기록합니다. 다시 말하지만, 시간 초과는 오류가 아니며 실제로 작성된 총 바이트 수는 count로 반환됩니다.
gensio를 사용한 동기 I/O 수행이 완료되면 다음을 호출하세요.
err = gensio_clear_sync ( io );
이벤트 인터페이스를 통한 전달은 이전과 동일하게 계속됩니다. 이것을 호출할 때 동기 읽기 또는 쓰기 호출에 있어서는 안 됩니다. 결과는 정의되지 않습니다.
동기식 I/O를 기다리는 동안 다른 gensio의 다른 I/O가 계속 발생한다는 점에 유의하세요.
현재 동기식 I/O를 사용하여 여러 gensio를 기다리는 방법은 없습니다. 그렇게 하려면 실제로 이벤트 중심 I/O를 사용해야 합니다. 그게 더 효율적이고 어쨌든 결국에는 같은 일을 하게 됩니다.
gensio와 마찬가지로 gensio 수용자는 생성 시 작동하지 않습니다. 활성화하려면 gensio_acc_startup()
호출해야 합니다.
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 }
언제 활성화되었는지 알기 위해 시작 호출에 대한 콜백이 없다는 점에 유의하세요. 쓸 수 없기 때문에 실제로 알 필요가 없고 콜백만 수행하기 때문입니다.
Accepter를 시작한 후에도 gensio_acc_set_accept_callback_enable()
호출하여 해당 콜백을 활성화할 때까지는 아무 작업도 수행하지 않습니다.
콜백이 호출되면 읽기가 비활성화된 상태로 이미 열려 있는 data
매개변수에 gensio가 제공됩니다. gensio 수용체로부터 받은 gensio에는 몇 가지 제한 사항이 있을 수 있습니다. 예를 들어, 닫았다가 다시 열 수 없을 수도 있습니다.
gensio 수락자는 gensio_acc_set_sync()
및 gensio_acc_accept_s
를 사용하여 동기 수락을 수행할 수 있습니다. 자세한 내용은 해당 매뉴얼 페이지를 참조하십시오.
struct gensio_os_funcs
에는 내부 gensio 로그를 처리하기 위한 vlog 콜백이 있습니다. 중요한 일이 발생했지만 gensio가 오류를 보고할 방법이 없을 때 호출됩니다. 또한 문제가 발생한 경우 문제를 더 쉽게 진단하기 위해 호출될 수도 있습니다.
gensio 및 gensio 수락자 클래스에는 각각 직렬 I/O를 처리하고 직렬 포트와 관련된 모든 매개변수를 설정하기 위한 하위 클래스가 있습니다.
gensio_to_sergensio()
호출하여 gensio(또는 그 하위 항목)가 직렬 포트인지 확인할 수 있습니다. NULL을 반환하면 sergensio가 아니며 해당 자식 중 어느 것도 sergensio가 아닙니다. NULL이 아닌 값을 반환하는 경우 사용할 수 있는 sergensio 개체를 반환합니다. sergensio_to_gensio()
에 의해 반환된 gensio는 gensio_to_sergensio()
에 전달된 gensio가 될 것이며 반드시 sergensio가 직접 연결된 gensio일 필요는 없습니다.
sergensio는 직렬 설정을 지정할 수 있는 클라이언트일 수도 있고, 연결의 다른 쪽 끝에서 직렬 설정을 수신하는 서버일 수도 있습니다.
대부분의 sergensios는 클라이언트 전용입니다: serialdev(일반 직렬 포트), ipmisol 및 stdio accepter. 현재는 텔넷에만 클라이언트와 서버 기능이 모두 있습니다.
참고: 여기에 설명된 Python 인터페이스는 더 이상 사용되지 않습니다. 이제 c++/swig/pygensio에 있는 것을 사용하세요.
Python을 통해 거의 모든 gensio 인터페이스에 액세스할 수 있지만 C 인터페이스와는 약간 다르게 수행됩니다.
Python은 완전히 객체 지향적이므로 gensios 및 gensio accepters는 gensio_os_funcs, sergensios 및 waiters와 함께 일류 객체입니다.
다음은 작은 프로그램입니다:
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 ()
인터페이스는 C 인터페이스를 매우 직접적으로 번역한 것입니다. 인터페이스의 Python 표현은 swig/python/gensiodoc.py에 있으며, 문서에서 이를 볼 수 있습니다.
C++ 인터페이스는 c++/README.rst에 문서화되어 있습니다.
새로운 pygensio 인터페이스는 Python에 직접 코딩한 콜백 대신 swig Director를 사용하여 더욱 깔끔하게 구현되었습니다. c++/swig/pygensio의 README.rst를 참조하세요. glib 및 tcl 디렉토리에는 glib 및 tcl OS_Funcs도 있습니다.
전체 C++ 인터페이스는 swig 및 swig 디렉터를 통해 Go 프로그램에서 사용할 수 있습니다. 자세한 내용은 c++/swig/go/README.rst를 참조하세요.
이것은 특별한 것이 아닌 일반적인 autoconf 시스템입니다. git에서 직접 가져오면 빌드 인프라가 포함되지 않습니다. 기본 디렉터리에 "reconf"라는 스크립트가 있어 이를 생성할 수 있습니다.
autoconf에 대해 모른다면 INSTALL 파일에 몇 가지 정보가 있거나 Google에서 검색해 보세요.
gensio를 완전히 빌드하려면 다음이 필요합니다.
다음은 우분투 20.04에서 openipmi를 제외한 모든 것을 설정합니다.
- sudo apt 설치 gcc g++ git swig python3-dev libssl-dev pkg-config
- libavahi-client-dev avahi-daemon libtool autoconf automake make libsctp-dev libpam-dev libwrap0-dev libglib2.0-dev tcl-dev libasound2-dev libudev-dev
Redhat에서는 libwrap이 사라졌으므로 이를 사용하지 않을 것이며 swig도 사용할 수 없는 것 같으므로 최소한 go 및 Python 지원을 사용하여 직접 빌드해야 합니다. Redhat과 유사한 시스템에 대한 명령은 다음과 같습니다.
- sudo yum 설치 gcc gcc-c++ git python3-devel swig openssl-devel
- pkg-config avahi-devel libtool autoconf autocake make lksctp-tools-devel pam-devel glib2-devel tcl-devel alsa-lib-devel systemd-devel
개발 패키지에 액세스하려면 다음을 수행해야 할 수도 있습니다.
sudo dnf config-manager-세트 가능 디벨
SCTP 커널 모듈을 얻으십시오.해야 할 수도 있습니다.
Sudo Yum을 설치 커널 모듈-엑스트라
Go Language를 사용하려면 SWIG 4.1.0 이상의 버전을 받아야합니다. 블러딩 엣지 버전을 git에서 뽑아서 사용해야 할 수도 있습니다.
파이썬 설치 구성을 처리하는 것은 약간의 고통입니다. 기본적으로 빌드 스크립트는 Python 프로그램이 설치된 Python 프로그램이 예상되는 곳에 어디에있게 도달합니다. 일반 사용자는 일반적으로 해당 디렉토리에 대한 쓰기 액세스가 없습니다.
이를 무시하기 위해-with-pythoninstall 및 -with-pythoninstalllib 옵션을 사용하거나 Pythoninstalldir 및 Pythoninstalllibdir 환경 변수를 라이브러리와 모듈을 원하는 곳으로 설정할 수 있습니다.
Lockdir로-uucp-locking을 설정해야 할 수도 있습니다 (이전 시스템에서는 기본값 인/var/lock입니다. 최신 경우/run/lek/lockdev 일 수도 있습니다. 직렬 장치 및/또는 잠금 장치를 열 수있는 전화기 및 잠금 그룹의 구성원.
Go Language Support는 Go를 설치해야합니다.
Crypto, MDNS, Sound, IPMI, SCTP 등과 같은 Library에 Gensios를 계속 추가하면서 라이브러리의 종속성 수는 제어에서 벗어났습니다. 필요하지 않은 경우 왜 libasound 또는 libopenipmi를로드해야합니까? 또한, 라이브러리는 프로그래밍 방식 API를 통해 자신의 Gensios를 추가하는 것을 지원하지만 시스템에 추가 할 수있는 표준 방법은 없었으므로 자신의 Gensio를 작성하고 시스템의 모든 사람이 사용할 수 있도록합니다.
Gensio 라이브러리는 Gensios 로딩을 동적으로 적재하거나 라이브러리에 제작하는 것을 지원합니다. 기본적으로 공유 라이브러리를 작성하면 모든 Gensios는 동적 로딩을위한 모듈로 컴파일되어 가능하게하는 장소에 설치됩니다. 공유 라이브러리를 만들지 않으면 모든 Gensios가 라이브러리에 내장되어 있습니다. 그러나이 동작을 무시할 수 있습니다.
모든 Gensios를 라이브러리에 내장하도록 설정하려면 구성 명령 줄에 "with-with-gensios = Yes"를 추가 할 수 있으며 라이브러리에 빌드 할 수 있습니다.
"with-with-Gensios = Dynamic"을 추가하여 동적으로로드 할 수 있지만 기본값입니다.
"with-all-gensios = no"를 지정하여 기본적으로 모든 Gensios를 비활성화 할 수도 있습니다. 그런 다음 기본적으로 Gensios가 구축되지 않습니다. 이것은 몇 개의 Gensios를 원한다면 유용합니다. 모든 Gensios를 끄고 원하는 것을 활성화 할 수 있습니다.
개별 Gensios가 구축되는 방식을 설정하려면 "-with- <gensio> = x"여기서 x는 "아니오 (빌드하지 않음), 예 (라이브러리로 빌드) 또는 동적 (동적으로로드 된 실행 가능)입니다. TCP Gensio를 라이브러리에 만 빌드하고 나머지를 동적으로 만들고 싶다면 모든 동적 인 Gensios를 설정 한 다음 "-with-net = yes"를 추가 할 수 있습니다.
이 모듈은 기본적으로 제출됩니다
라이브러리의 모든 Gensios를 구축하더라도 동적 로딩은 항상 사용할 수 있습니다. 따라서 여전히 적절한 디렉토리에 추가하여 자신의 Gensios를 추가 할 수 있습니다.
Gensios는 환경 변수 ld_library_path에서 먼저로드 한 다음 Gensio_library_path에서 기본 위치에서로드됩니다.
일종의 * 닉스 인 MacOS는 홈브류 (https://brew.sh)로 매우 깨끗하게 구축됩니다. 물론 필요한 모든 라이브러리를 설치해야합니다. 대부분의 모든 것이 다음과 같이 작동합니다.
* CM108GPIO * SCTP * UUCP 잠금
내장 된 DNSSD 코드는 MDNS에 사용되므로 Avahi가 필요하지 않습니다.
직렬 포트의 플록 잠금은 작동하므로 UUCP 잠금이 실제로 필요하지 않습니다.
OpenIPMI는 작동해야하지만 홈브류에서는 사용할 수 없으므로 직접 구축해야합니다.
필요한 소프트웨어 설치 :
- PKG 설치 GCC PORTAUDIO AUTOCONF AUTOMAKE LIBTOOL MDNSRESPONDER SWIG
- Python3 Gmake로 가십시오
GMAKE를 사용하여 컴파일해야합니다. 어떤 이유로 BSD의 표준이 요구 사항 목록에서 "C ++"변수를 허용하지 않습니다. 다음은 작동하지 않으며 편집되지 않습니다.
* SCTP * IPMISOL * CM108GPIO
/etc/rc.conf에 다음을 추가하십시오.
mdnsd_enable = 예
재부팅하거나 서비스를 시작하십시오.
Pty Gensio는 Oomtest (Oomtest 14)에 실패하며 BSD Ptys에는 무언가가있는 것 같습니다. 케이스에서 데이터 스트림에 07 문자가 삽입되어 있습니다. 그래도 나는 그것에 너무 많은 시간을 소비하지 않았지만, 이것은 Linux와 MacOS에서 심하게 테스트되었으므로 문제가 Gensio 코드에 있다고 생각하지 않습니다.
Gensio 라이브러리는 Mingw64를 사용하여 창 아래에 구축 할 수 있습니다. 다음은 작동하지 않습니다.
* SCTP * PAM * libwrap * IPMISOL
또한 ALSA를 설치할 필요가 없으며 사운드에 Windows 사운드 인터페이스를 사용합니다.
CM108GPIO는 기본 Windows 인터페이스를 사용하므로 UDEV가 필요하지 않습니다.
Windows 내장 MDNS 인터페이스가 사용되므로 Avahi 또는 DNSSD가 필요하지 않습니다. 정규 표현식을 원하는 경우 PCRE 라이브러리를 설치해야합니다.
https://msys2.org에서 msys2를 가져와야합니다. 그런 다음 Autoconf, Automake, Libtool, Git, Make 및 Swig를 호스트 도구로 설치하십시오.
Pacman -S Autoconf Automake libtool git make swig
모든 라이브러리 또는 모든 라이브러리의 Mingw-W64-X86_64-XXX 버전을 설치해야합니다. 32 비트는 잘 테스트되지 않았습니다.
Pacman -S Mingw-W64-x86_64-GCC mingw-w64-x86_64-python3 mingw-w64-x86_64-pcre Mingw-W64-x86_64- 오렌지 스플
Mingw64 또는 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- 오펜스 슬링
이동하려면 https://go.dev에서 이동하여 로그 아웃하고 로그 아웃하십시오. 그런 다음 경로에 있어야하지만 그렇지 않은 경우 경로에 추가해야합니다. 나는 mingw32에서 작업하지 않았지만 32 비트 버전의 Go를 시도하지 않았습니다.
gtlsshd의 경우 -sysconfdir는 Windows에 의미가 없습니다. 대신, sysconf dir는 in ../etc/gtlssh에서 실행 파일의 패치와 관련이 있습니다. 따라서 gtlsshd가있는 경우 :
C :/프로그램 파일/gensio/bin/gtlsshd
sysconfdir는 다음과 같습니다.
C :/프로그램 파일/gensio/etc/gtlssh
표준 설치의 경우 다음을 실행할 수 있습니다.
../configure ---sbindir =/gensio/bin -libexecdir =/gensio/bin -Mandir =/gensio/man-includedir =/gensio/include -with-pythoninstall =/gensio/python3--prefix =/gensio
그리고 당신이 "destdir = ... ..."를 실행할 때 "c :/program files"와 같이 Destdir를 원하는 곳으로 설정했습니다. 그런 다음 제어판을 사용하여 경로에 추가 할 수 있습니다. GTLSSHD를 사용하려면 Gensio 디렉토리에 ETC/GTLSSHD 디렉토리를 만듭니다. 시스템과 관리자 만 액세스 할 수 있도록이 디렉토리의 권한을 설정해야합니다.
ps c : program files (x86) gensio etc> icacls gtlssh GTLSSH NT Authority 시스템 : (OI) (CI) (F) 내장 관리자 : (oi) (ci) (f)
그렇지 않으면 gtlsshd는 키의 권한에 대한 오류로 실패합니다. 디렉토리 대신 .key 파일 에서이 권한을 설정할 수 있지만 새 키를 생성 할 때마다 다시 설정해야합니다.
Inno 설정 컴파일러를 사용하려면 "Destdir = $ home/install"을 설치 한 다음 gensio.iss에서 inno를 실행하십시오. Gensio 설치를위한 실행 가능한 설치 프로그램을 만듭니다.
그런 다음 다른 것들과 링크 할 때 설치 디렉토리에서 .la 파일을 제거해야합니다.
Rm $ 홈/설치/Gensio/lib/*. la
Gensios에 대한 여러 가지 테스트가 있습니다. SerialSim 커널 모듈이 있으면 모두 Linux에서 실행됩니다. 직렬 포트 외에도 Gensios가 해당 플랫폼에서 지원되므로 다른 플랫폼에서 실행됩니다.
직렬 포트 테스트에는 직렬 커널 모듈 및 파이썬 인터페이스가 필요합니다. 이들은 https://github.com/cminyard/serialsim에 있으며 테스트에서 시뮬레이션 된 직렬 포트를 사용하여 모뎀 제어 라인, 주입 오류 등을 읽습니다.
세 개의 직렬 장치가 있으면 직렬 장치없이 얻을 수 있습니다. 하나는 에코 모드 (RX 및 TX가 함께 묶여 있음)와 함께 연결된 2 개의 직렬 장치가 I/O를 연결하여 다른 장치로 이동합니다. 이것은 비 명 플랫폼에서 작동해야합니다. 그런 다음 다음 환경 변수를 설정하십시오.
export GENSIO_TEST_PIPE_DEVS= " /dev/ttyxxx:/dev/ttywww "
export GENSIO_TEST_ECHO_DEV= " /dev/ttyzzz "
Modemstate 또는 RS485를 테스트 할 수 없습니다.
또한 https://github.com/cminyard/openipmi의 OpenIPMI 라이브러리에서 IPMI_SIM 프로그램이 필요합니다.
테스트를 실행하려면 내부 디버깅을 활성화하여 전체 효과를 얻을 수 있어야합니다. 일반적으로 다음과 같은 것을 실행하고 싶습니다.
./configure --enable-internal-trace CFLAGS= ' -g -Wall '
원한다면 CFLAG에서 -O3을 켜도 디버깅을 어렵게 만듭니다.
두 가지 기본 유형의 테스트가 있습니다. 파이썬 테스트는 Python 인터페이스와 Gensio 라이브러리를 모두 테스트하는 기능 테스트입니다. 현재는 괜찮지 만 개선의 여지가 충분합니다. 도와주고 싶다면 테스트를 작성할 수 있습니다.
Oomtest는 메모리 외 테스터 였지만 더 광범위한 것으로 변형되었습니다. 특정 환경 변수가있는 Gensiot 프로그램을 생성하여 특정 지점에서 실패하고 메모리 누출 및 기타 메모리 검사를 수행합니다. 그것은 stdin을 통해 Gensiot에 데이터를 작성하고 stdout에 대한 데이터를 수신합니다. SerialDev와 같은 일부 테스트는 에코를 사용합니다. 다른 테스트는 네트워크를 통해 별도의 연결을 만들고 데이터는 stdin으로 흐르고 별도의 연결로 돌아와 별도의 연결로 흐르고 stdout을 통해 돌아옵니다. Oomtest는 다중 스레드이며 스레드 수를 제어 할 수 있습니다. Oomtest는 많은 버그를 발견했습니다. 손잡이가 많지만 옵션의 소스 코드를 살펴 봐야합니다. 누군가 자원 봉사를 원한다면 문서화해야합니다 ...
퍼지를 설정하려면 AFL을 설치 한 다음 다음으로 구성하십시오.
mkdir Zfuzz ; cd Zfuzz
../configure --enable-internal-trace=yes --disable-shared --with-go=no
CC=afl-gcc CXX=afl-g++
또는 가능한 경우 Clang을 사용하십시오.
../configure --enable-internal-trace=yes --disable-shared --with-go=no
CC=afl-clang-fast CXX=afl-clang-fast++ LIBS= ' -lstdc++ '
나는 왜 위에 libs가 필요한지 잘 모르겠지만 그것을 컴파일하기 위해 그것을 추가해야했습니다.
그런 다음 빌드하십시오. 그런 다음 "CD Tests"및 실행 "XXX는 CERTAUTH, MUX, SSL, TELNET 또는 RELPKT 중 하나입니다. AFL이 당신에게 말할 것입니다. 영원히 실행됩니다. 완료되면 ^C를 필요로합니다.
tests/makefile.am의 makefile에는 디버깅을 재현하지 못하는 방법에 대한 지침이 있습니다.
라이브러리에서 코드 범위를 실행하는 것은 매우 쉽습니다. 먼저 커버리지를 활성화하려면 코드를 구성해야합니다.
mkdir Ocov ; cd Ocov
../configure --enable-internal-trace=yes
CC= ' gcc -fprofile-arcs -ftest-coverage '
CXX= ' g++ -fprofile-arcs -ftest-coverage '
컴파일 및 실행 "확인".
보고서를 생성하려면 실행하십시오.
gcovr -f ' .*/.libs/.* ' -e ' .*python.* '
이것은 요약을 생성합니다. 파일에서 개별 라인의 적용 범위를보고 싶다면 다음을 수행 할 수 있습니다.
cd lib
gcov -o .libs/ * .o
다루는 내용에 대한 정보를 위해 생성 된 개별 .gcov 파일을 볼 수 있습니다. 자세한 내용은 GCOV 문서를 참조하십시오.
글을 쓰는 시점에서 나는 약 74%의 코드 범위를 받고 있었기 때문에 정말 좋습니다. 나는 주로 개선 된 기능 테스트를 통해 그것을 개선하기 위해 노력할 것입니다.
Ser2Net은 주로 직렬 포트 구성 (Termios 및 RFC2217)을 테스트하는 데 사용됩니다. Gensio Library의 GCOV 버전에 대해 SER2NET을 구축하고 SER2NET에서 "Make Check"를 실행하여 해당 부품에 대한 적용 범위를 얻을 수 있습니다. 이를 통해 약 76%의 적용 범위를보고 있으므로 총계에 크게 추가되지 않습니다.
이것을 퍼징과 결합 할 수있어서 좋을 것이지만 어떻게 해야할지 잘 모르겠습니다. AFL은 코드 커버리지로 고유 한 작업을 수행합니다. 어떻게 든 GCOV를 통합 한 AFL-COV 패키지가있는 것으로 보이지만 조사하지 않았습니다.