Digamos que tengo 2 procesos, ProcessA y ProcessB. Si realizo int fd=open(somefile)
en ProcessA, ¿puedo pasar el valor del descriptor de archivo fd
sobre IPC a ProcessB y hacer que manipule el mismo archivo?¿Puedo compartir un descriptor de archivo en otro proceso en Linux o son locales para el proceso?
Respuesta
Puede pasar un descriptor de archivo a otro proceso a través de sockets unix domain. Aquí está el código para pasar un descriptor de tal archivo, tomada de Unix Network Programming
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 */
Y aquí está el código para recibir el descriptor de archivo
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 */
Sin embargo, tenga en cuenta que el valor numérico real del descriptor de archivo será, en general, diferente en los dos procesos. – caf
Puede pasar el * número * de esta manera. Eso no significa mágicamente que funcione como un descriptor de archivo para el mismo archivo en ambos extremos. – EJP
@EJP La idea con SCM_RIGHTS es que lo hará. Aunque ninguno viene a la mente, estoy seguro de que hay algunas advertencias. (es decir, el concepto funciona más o menos como dup(), pero entre procesos no relacionados) – nos
Puede utilizar los números método descrito en este tema, con el (más convencional) forma, al compartirlo entre los procesos relacionados (típicamente padres-hijos o hermanos) al tenerlo creado, los procesos bifurcados reciben automáticamente una copia.
De hecho, los procesos bifurcados obtienen todos sus FD y pueden usarlos a menos que los cierren (lo que generalmente es una buena idea).
Por lo tanto, si un padre usa dos hijos, si ambos tienen un descriptor de archivo que no cerraron, ahora se comparte (incluso si el padre lo cierra posteriormente). Esto podría, por ejemplo, ser una tubería de un niño a otro. Así es como redireccionamientos shell como
ls -l | more
Trabajo. No se requiere
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;
:
Tenga en cuenta que en el ejemplo de arriba, el ajuste de las variables cuando se recibe, como. La idea de una estructura de mensaje con encabezados es que el sitio receptor no tiene que saber lo que lee y puede verificar el (primer) encabezado, qué tipo de mensaje es y qué esperar.
Aunque es técnicamente correcto, hay una buena razón para especificar un búfer en este caso: para enviar un mensaje OOB (el mensaje de control de socket) en este caso), debe especificar un mensaje no vacío (consulte unix_stream_sendmsg, por ejemplo, http://lxr.free-electrons.com/source/net/unix/af_unix.c#L1836). Al recibir sin un iovec, Linux entregará ese mensaje una y otra vez. Por lo tanto, para leer más de un mensaje OOB, DEBE leer los datos del mensaje en algún momento. – Michael
Si ambos procesos pertenecen al mismo usuario, entonces simplemente puede hacer uso de los 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);
Por supuesto que tendría que algún mecanismo IPC para compartir el valor de SOURCE_FD
. Ver p. "Linux C: upon receiving a signal, is it possible to know the PID of the sender?".
- 1. Cómo cerrar un descriptor de archivo de otro proceso en sistemas Unix
- 2. Cómo esperar a que finalice un proceso para ejecutar otro proceso en el archivo por lotes
- 3. ¿Ejecuta un proceso desde la memoria dentro de otro proceso?
- 4. En Linux, ¿podría un proceso representar la GUI de otro proceso?
- 5. ¿Cómo uso el comando linux flock para evitar que otro proceso raíz elimine un archivo?
- 6. ¿Cómo puedo usar nohup para ejecutar el proceso como proceso en segundo plano en Linux?
- 7. ¿Cómo puede un proceso interceptar stdout y stderr de otro proceso en Linux?
- 8. Proceso de fondo en Linux
- 9. ¿Los identificadores de proceso no son negativos en Linux?
- 10. arrastre a otro proceso
- 11. ¿Es posible que un proceso Java en un jvm mate/detenga otro proceso java en otro jvm?
- 12. .NET - TextWriterTraceListener, el archivo está en uso por otro proceso
- 13. archivo está siendo utilizado por otro proceso
- 14. de archivo usado por otro proceso
- 15. ¿Cómo detener el proceso 'ininterrumpible' en Linux?
- 16. ¿Es posible UAC elevar un proceso sin iniciar otro proceso?
- 17. ¿Puedo abrir un socket y pasarlo a otro proceso en Linux
- 18. Cambiar el nombre del proceso en Linux
- 19. Microsegundo (o mejor) sincronización del proceso en Linux
- 20. Cómo iniciar un proceso detenido en Linux
- 21. Tablas de páginas para caminar de un proceso en Linux
- 22. Lectura de un archivo utilizado por otro proceso
- 23. Cambiar diseño de teclado para otro proceso
- 24. Cambiar el propietario de un proceso existente en Linux
- 25. ¿Se puede representar una ventana de Direct3D para un proceso en otro proceso 'HWND?
- 26. linux: ¿obteniendo umask de un proceso ya en ejecución?
- 27. El proceso no puede acceder al archivo porque lo está utilizando otro proceso
- 28. Determinar el motivo de un proceso detenido en Linux
- 29. Proceso de reinicio en el cambio de archivos en Linux
- 30. Linux - Encuentra si el proceso está listo o correr
Duplicado: http://stackoverflow.com/questions/1997622 – Zitrax
Ver [esta pregunta] (http://stackoverflow.com/questions/1997622). – bmargulies