Linux 상의 다른 프로세스와 파일 기술자를 공유할 수 있습니까?아니면 로컬 프로세스입니까?
예를 들어 프로세스 A와 프로세스 B의 2가지 프로세스가 있다고 합시다.제가 공연을 하면int fd=open(somefile)
프로세스 A에서 파일 기술자의 값을 전달할 수 있습니까?fd
IPC를 경유하여 프로세스 B에 접속하여 동일한 파일을 조작하고 있는지 확인합니다.
UNIX 도메인 소켓을 통해 파일 기술자를 다른 프로세스에 전달할 수 있습니다.다음은 UNIX 네트워크 프로그래밍에서 가져온 이러한 파일 기술자를 전달하기 위한 코드입니다.
ssize_t
write_fd(int fd, void *ptr, size_t nbytes, int sendfd)
{
struct msghdr msg;
struct iovec iov[1];
#ifdef HAVE_MSGHDR_MSG_CONTROL
union {
struct cmsghdr cm;
char control[CMSG_SPACE(sizeof(int))];
} control_un;
struct cmsghdr *cmptr;
msg.msg_control = control_un.control;
msg.msg_controllen = sizeof(control_un.control);
cmptr = CMSG_FIRSTHDR(&msg);
cmptr->cmsg_len = CMSG_LEN(sizeof(int));
cmptr->cmsg_level = SOL_SOCKET;
cmptr->cmsg_type = SCM_RIGHTS;
*((int *) CMSG_DATA(cmptr)) = sendfd;
#else
msg.msg_accrights = (caddr_t) &sendfd;
msg.msg_accrightslen = sizeof(int);
#endif
msg.msg_name = NULL;
msg.msg_namelen = 0;
iov[0].iov_base = ptr;
iov[0].iov_len = nbytes;
msg.msg_iov = iov;
msg.msg_iovlen = 1;
return(sendmsg(fd, &msg, 0));
}
/* end write_fd */
여기 파일 설명자를 받을 수 있는 코드가 있습니다.
ssize_t
read_fd(int fd, void *ptr, size_t nbytes, int *recvfd)
{
struct msghdr msg;
struct iovec iov[1];
ssize_t n;
int newfd;
#ifdef HAVE_MSGHDR_MSG_CONTROL
union {
struct cmsghdr cm;
char control[CMSG_SPACE(sizeof(int))];
} control_un;
struct cmsghdr *cmptr;
msg.msg_control = control_un.control;
msg.msg_controllen = sizeof(control_un.control);
#else
msg.msg_accrights = (caddr_t) &newfd;
msg.msg_accrightslen = sizeof(int);
#endif
msg.msg_name = NULL;
msg.msg_namelen = 0;
iov[0].iov_base = ptr;
iov[0].iov_len = nbytes;
msg.msg_iov = iov;
msg.msg_iovlen = 1;
if ( (n = recvmsg(fd, &msg, 0)) <= 0)
return(n);
#ifdef HAVE_MSGHDR_MSG_CONTROL
if ( (cmptr = CMSG_FIRSTHDR(&msg)) != NULL &&
cmptr->cmsg_len == CMSG_LEN(sizeof(int))) {
if (cmptr->cmsg_level != SOL_SOCKET)
err_quit("control level != SOL_SOCKET");
if (cmptr->cmsg_type != SCM_RIGHTS)
err_quit("control type != SCM_RIGHTS");
*recvfd = *((int *) CMSG_DATA(cmptr));
} else
*recvfd = -1; /* descriptor was not passed */
#else
/* *INDENT-OFF* */
if (msg.msg_accrightslen == sizeof(int))
*recvfd = newfd;
else
*recvfd = -1; /* descriptor was not passed */
/* *INDENT-ON* */
#endif
return(n);
}
/* end read_fd */
2020년에 Linux 버전 5.6 이상에서는 새로운 시스템콜이 Linux에 추가되어 프로세스가 pidfd에 의해 참조되는 다른 프로세스의 파일 기술자의 복제를 취득할 수 있게 되었습니다.pidfd_getfd()
시스템 콜을 실행합니다.
양쪽 프로세스가 같은 유저에 속하는 경우는, 간단하게 procfs 를 사용할 수 있습니다.
char fd_path[64]; // actual maximal length: 37 for 64bit systems
snprintf(fd_path, sizeof(fd_path), "/proc/%d/fd/%d", SOURCE_PID, SOURCE_FD);
int new_fd = open(fd_path, O_RDWR);
물론 IPC 메커니즘이 있어야 가치를 공유할 수 있습니다.SOURCE_FD
. 를 참조해 주세요."Linux C: 신호를 수신하면 송신자의 PID를 알 수 있습니까?"
이 스레드에 기술되어 있는nos 메서드를 사용하거나 (일반적으로 부모-자녀 또는 형제자매) 관련 프로세스 간에 공유함으로써 분기된 프로세스가 자동으로 복사본을 수신할 수 있습니다.
실제로 분기된 프로세스는 모든 FD를 취득하고 FD를 닫지 않는 한 FD를 사용할 수 있습니다(일반적으로 이 방법이 좋습니다).
따라서 부모가 두 아이를 포킹하고 둘 다 닫지 않은 파일 설명자가 있는 경우, 이제 공유됩니다(부모가 나중에 닫더라도).예를 들어, 이것은 한 아이에서 다른 아이로 가는 파이프일 수 있습니다.셸 리다이렉트 방법은 다음과 같습니다.
ls -l | more
일하다.
위의 예에서는 수신 시 변수의 설정은 다음과 같습니다.
msg.msg_name = NULL;
msg.msg_namelen = 0;
iov[0].iov_base = ptr;
iov[0].iov_len = nbytes;
msg.msg_iov = iov;
msg.msg_iovlen = 1;
는 필수가 아닙니다.헤더가 있는 메시지 구조의 전체 개념은 수신 사이트가 무엇을 읽는지 알 필요가 없으며, (첫 번째) 헤더를 체크함으로써 어떤 종류의 메시지인지, 무엇을 예상할 수 있다는 것입니다.
언급URL : https://stackoverflow.com/questions/2358684/can-i-share-a-file-descriptor-to-another-process-on-linux-or-are-they-local-to-t
'programing' 카테고리의 다른 글
C로 시간(NULL)은 무엇입니까? (0) | 2022.07.31 |
---|---|
size of(char) != 1 또는 CHAR_B 이상의 시스템이 있습니까?IT > 8? (0) | 2022.07.31 |
tcmalloc/jemalloc와 메모리 풀의 차이점(및 선택해야 하는 이유)은 무엇입니까? (0) | 2022.07.31 |
Vue.js 디버깅메시지 문제 (0) | 2022.07.31 |
개인 메서드를 호출할 방법이 있나요? (0) | 2022.07.31 |