{"id":27455040,"url":"https://github.com/devlights/fdpassing","last_synced_at":"2026-05-03T05:44:27.942Z","repository":{"id":287830679,"uuid":"965926818","full_name":"devlights/fdpassing","owner":"devlights","description":"A Go library for file descriptor passing","archived":false,"fork":false,"pushed_at":"2025-04-14T07:57:43.000Z","size":9,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-05-03T05:44:26.278Z","etag":null,"topics":["file-descriptor-passing","golang","linux","scm-rights"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/devlights.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-04-14T06:12:45.000Z","updated_at":"2025-04-14T07:57:22.000Z","dependencies_parsed_at":"2025-04-15T15:16:29.240Z","dependency_job_id":null,"html_url":"https://github.com/devlights/fdpassing","commit_stats":null,"previous_names":["devlights/fdpassing"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/devlights/fdpassing","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devlights%2Ffdpassing","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devlights%2Ffdpassing/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devlights%2Ffdpassing/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devlights%2Ffdpassing/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/devlights","download_url":"https://codeload.github.com/devlights/fdpassing/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devlights%2Ffdpassing/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32559716,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-03T03:21:47.309Z","status":"ssl_error","status_checked_at":"2026-05-03T03:21:43.884Z","response_time":103,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["file-descriptor-passing","golang","linux","scm-rights"],"created_at":"2025-04-15T15:16:27.977Z","updated_at":"2026-05-03T05:44:27.927Z","avatar_url":"https://github.com/devlights.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# fdpassing\n\nA Go library for file descriptor passing. Utilizing Unix domain sockets, this library enables safe file descriptor transfers between processes.\n\n## What is File Descriptor Passing?\n\nFile Descriptor Passing (FD passing) is a technique for transferring an already opened file descriptor from one process to another. In Unix systems, resources such as files, sockets, and pipes are represented by integer values called file descriptors within a process.\n\nWhile each process typically maintains its own file descriptor table, Unix domain sockets' `SCM_RIGHTS` feature enables the transfer of file descriptors from one process to another, allowing both processes to access the same resource.\n\n**Key benefits:**\n\n- Resource sharing: Multiple processes can share the same file or socket\n- Performance improvement: Transfer only the file descriptor without copying large data\n- Privilege delegation: Privileged processes can safely pass resources to non-privileged processes\n- Graceful service restart: Server processes can transfer connections to new processes when restarting without losing connections\n\n**Technical mechanism:**\n\nFile descriptor passing is implemented using the ancillary data feature of Unix domain sockets. The sending process includes the file descriptor in a control message, and the kernel duplicates that file descriptor into the receiving process's file descriptor table. This provides the receiving process with a new file descriptor to the same resource.\n\n## Overview\n\nThe `fdpassing` package provides a simple wrapper around the `SCM_RIGHTS` feature of Unix domain sockets to transfer file descriptors from one process to another. File descriptor passing is particularly useful when sharing opened files, sockets, pipes, etc. between processes.\n\nThis library provides the following key functions:\n\n- Sending a single file descriptor (`Send` method)\n- Receiving a single file descriptor (`Recv` method)\n\n**Note**: The current implementation supports sending and receiving only one file descriptor at a time. To transfer multiple file descriptors, you need to call the Send/Recv methods multiple times.\n\n## Usage\n\n### Installation\n\n```bash\ngo get github.com/devlights/fdpassing\n```\n\n### Basic Examples\n\n#### Sender Process\n\n```go\npackage main\n\nimport (\n\t\"log\"\n\t\"net\"\n\t\"os\"\n\t\n\t\"github.com/devlights/fdpassing\"\n)\n\nfunc main() {\n\t// Unix socket path\n\tsocketPath := \"/tmp/fd_socket\"\n\t\n\t// Remove existing socket\n\tos.Remove(socketPath)\n\t\n\t// Create listener\n\tlistener, err := net.ListenUnix(\"unix\", \u0026net.UnixAddr{Name: socketPath, Net: \"unix\"})\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create listener: %v\", err)\n\t}\n\tdefer listener.Close()\n\t\n\tlog.Printf(\"Waiting for connection: %s\", socketPath)\n\t\n\t// Accept client connection\n\tconn, err := listener.AcceptUnix()\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to accept connection: %v\", err)\n\t}\n\tdefer conn.Close()\n\t\n\t// Open file to be sent\n\tfile, err := os.Open(\"/path/to/your/file.txt\")\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to open file: %v\", err)\n\t}\n\t\n\t// Create fdpassing instance\n\tfdSender := fdpassing.NewFd(conn)\n\t\n\t// Send file descriptor\n\terr = fdSender.Send(int(file.Fd()))\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to send FD: %v\", err)\n\t}\n\t\n\tlog.Println(\"File descriptor sent successfully\")\n}\n```\n\n#### Receiver Process\n\n```go\npackage main\n\nimport (\n\t\"io\"\n\t\"log\"\n\t\"net\"\n\t\"os\"\n\t\n\t\"github.com/devlights/fdpassing\"\n)\n\nfunc main() {\n\t// Unix socket path\n\tsocketPath := \"/tmp/fd_socket\"\n\t\n\t// Connect to server\n\tconn, err := net.DialUnix(\"unix\", nil, \u0026net.UnixAddr{Name: socketPath, Net: \"unix\"})\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to connect to server: %v\", err)\n\t}\n\tdefer conn.Close()\n\t\n\t// Create fdpassing instance\n\tfdReceiver := fdpassing.NewFd(conn)\n\t\n\t// Receive file descriptor\n\treceivedFd, err := fdReceiver.Recv()\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to receive FD: %v\", err)\n\t}\n\t\n\t// Create file from received file descriptor\n\tfile := os.NewFile(uintptr(receivedFd), \"received-file\")\n\tdefer file.Close()\n\t\n\t// Read file content\n\tcontent, err := io.ReadAll(file)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to read file: %v\", err)\n\t}\n\t\n\tlog.Printf(\"Content of received file:\\n%s\", content)\n}\n```\n\n## When This Library Is Effective\n\nThe `fdpassing` library is particularly useful in the following scenarios:\n\n1. **Multi-process architectures**: When a parent process needs to pass opened files or sockets to child processes\n\n2. **Privilege delegation**: When a process running with high privileges needs to pass file descriptors to a process with lower privileges\n\n3. **Zero-copy communication**: When transferring large amounts of data between processes, improving performance by transferring only file descriptors without copying the data\n\n4. **Hot reloading**: When migrating existing connections to a new process without restarting a service\n\n5. **Sandboxed processes**: When allowing access only to specific files for processes running in restricted environments\n\n6. **Unix socket communications**: When adding file descriptor passing capabilities to systems already using Unix domain sockets for IPC (Inter-Process Communication)\n\n### Limitations\n\n- This library works only on Unix-based systems (Linux, macOS, FreeBSD, etc.). Windows is not supported.\n- The sending and receiving processes must be running on the same host machine. File descriptor passing across network boundaries is not supported.\n- The current implementation supports sending and receiving only one file descriptor per operation.\n- The caller must explicitly close received file descriptors after use (by calling the `Close()` method on the file created with `os.NewFile`).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevlights%2Ffdpassing","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdevlights%2Ffdpassing","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevlights%2Ffdpassing/lists"}