Ya, linux secara otomatis "membersihkan" soket abstrak sejauh pembersihan bahkan masuk akal. Berikut ini contoh kerja minimal yang dapat Anda verifikasi ini:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
int
main(int argc, char **argv)
{
int s;
struct sockaddr_un sun;
if (argc != 2 || strlen(argv[1]) + 1 > sizeof(sun.sun_path)) {
fprintf(stderr, "usage: %s abstract-path\n", argv[0]);
exit(1);
}
s = socket(AF_UNIX, SOCK_STREAM, 0);
if (s < 0) {
perror("socket");
exit(1);
}
memset(&sun, 0, sizeof(sun));
sun.sun_family = AF_UNIX;
strcpy(sun.sun_path + 1, argv[1]);
if (bind(s, (struct sockaddr *) &sun, sizeof(sun))) {
perror("bind");
exit(1);
}
pause();
}
Jalankan program ini sebagai ./a.out /test-socket &
, lalu jalankan ss -ax | grep test-socket
, dan Anda akan melihat soket yang digunakan. Kemudian kill %./a.out
, dan ss -ax
akan ditampilkan soket yang hilang.
Namun, alasan Anda tidak dapat menemukan pembersihan ini dalam dokumentasi apa pun adalah karena itu tidak benar-benar membersihkan dalam arti yang sama bahwa soket unix-domain non-abstrak perlu dibersihkan. Soket non-abstrak sebenarnya mengalokasikan inode dan membuat entri dalam direktori, yang perlu dibersihkan di sistem file yang mendasarinya. Sebaliknya, pikirkan soket abstrak yang lebih mirip nomor port TCP atau UDP. Tentu, jika Anda mengikat port TCP dan kemudian keluar, port TCP itu akan bebas lagi. Tetapi berapa pun angka 16-bit yang Anda gunakan masih ada secara abstrak dan selalu dilakukan. Namespace nomor port adalah 1-65535 dan tidak pernah berubah atau perlu dibersihkan.
Jadi pikirkan saja nama soket abstrak seperti nomor port TCP atau UDP, baru saja memilih dari sekumpulan nomor port yang jauh lebih besar yang kebetulan terlihat seperti nama path tetapi tidak. Anda tidak dapat mengikat nomor port yang sama dua kali (kecuali SO_REUSEADDR
atau SO_REUSEPORT
). Tetapi menutup soket (secara eksplisit atau implisit dengan mengakhiri) membebaskan port, tanpa ada yang tersisa untuk dibersihkan.