Cờ FD_CLOEXEC fcntl () làm gì?


82

Như vậy:

if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) {
...

Mặc dù tôi đã đọc man fcntl, tôi không thể hiểu nó làm gì.

Câu trả lời:


74

Nó đặt cờ đóng-trên-thực thi cho bộ mô tả tệp, làm cho bộ mô tả tệp được đóng tự động (và nguyên tử) khi bất kỳ exechàm -family nào thành công.

Nó cũng kiểm tra giá trị trả về để xem liệu hoạt động có thất bại hay không, điều này khá vô ích nếu bộ mô tả tệp hợp lệ, vì không có điều kiện nào mà hoạt động này sẽ thất bại trên bộ mô tả tệp hợp lệ.


4
Lưu ý rằng nó không có tác dụng gì về việc xóa bất kỳ luồng tệp nào ( FILE *) được liên kết với trình mô tả tệp. Một cách sử dụng hợp lệ cho FD_CLOEXEC là đóng tệp nhật ký mà quy trình mẹ đã mở khi thực hiện quy trình shell. Lưu ý rằng POSIX 2008 có một tùy chọn open(2)cho O_CLOEXEC - vì vậy bạn có thể đặt thuộc tính này khi mở tệp, điều này sẽ rất hữu ích khi nó được phổ biến rộng rãi.
Jonathan Leffler

Đặt cờ nguyên tử khi tệp được mở là khá cần thiết đối với bất kỳ chương trình luồng nào có thể đang mở tệp trong khi một luồng khác có thể đang thực thi các chương trình bên ngoài. Đáng tiếc là nó chỉ có sẵn cho openvà không accept, socket, pipe, vv ...
R .. GitHub DỪNG GIÚP ICE

Có - có vấn đề thiết kế khi thêm O_CLOEXEC hoặc tương đương với các chức năng tạo bộ mô tả tệp khác (mặc dù dup()dup2()không bị ảnh hưởng, tất nhiên). Bạn có thể phải có các chức năng mới với tham số 'mode' hoặc 'flags' bổ sung, đó có lẽ là lý do tại sao nó không xảy ra. Nếu bạn có thể sử dụng O_CLOEXEC trên socket, thì bạn có thể giả sử rằng nó accept()sẽ sao chép cờ đó trên bộ mô tả mà nó trả về. Nhưng socket()pipe()phức tạp hơn.
Jonathan Leffler

3
dupdup2bị ảnh hưởng. Cờ đóng trên thực thi áp dụng cho các bộ mô tả tệp, không áp dụng cho các mô tả tệp đang mở, do đó, nó không được chia sẻ trên các bộ mô tả tệp trùng lặp. Đó là một điều rất tốt.
R .. GitHub NGỪNG TRỢ GIÚP TỪ NGÀY

3
Theo dõi trên cuộc nói chuyện trong các ý kiến, POSIX đã áp dụng để đưa vào ấn bản kế giao diện mới mà sửa chữa những thiếu sót: dup3, pipe2, và accept4. Ngoài ra, socketSOCK_CLOEXECcờ bạn có thể kết hợp với loại ổ cắm được yêu cầu.
R .. GitHub DỪNG TRỢ GIÚP ICE

33

Nó đánh dấu bộ mô tả tệp để nó sẽ được close()d tự động khi tiến trình hoặc bất kỳ phần tử con nào mà nó fork()gọi một trong các exec*()họ hàm. Điều này rất hữu ích để tránh làm rò rỉ bộ mô tả tệp của bạn cho các chương trình ngẫu nhiên chạy bởi vd system().


Đây có phải là một mối quan tâm về bảo mật?
zach

1
@zach bạn có thể nói như vậy; nhưng thực sự thì bất kỳ quá trình tái cấu trúc nào bạn thực hiện, chẳng hạn như đóng gói logic phân tán vào một thực thể, có thể được gọi là "mối quan tâm về bảo mật", bởi vì nó làm giảm xác suất lỗi do sử dụng sai thực thể đó và "lỗi" là một điều trừu tượng điều đó bao gồm mặc định và rò rỉ thông tin nói riêng.
Hi-Angel

Vì vậy, tôi đang cấu trúc lại một số mã ổ cắm và giữa việc đưa ổ cắm và kết nối () vào máy chủ từ xa, họ sử dụng F_SETFD để thêm cờ FD_CLOEXEC vào FD của ổ cắm. Sau đó, sau khi kết nối thành công, FD_CLOEXEC sẽ bị xóa. Tôi không thể tìm thấy bất kỳ lệnh gọi thực thi () nào liên quan đến vùng mã này và tôi tự hỏi liệu chúng có phải là tàn dư của mã cũ đáng lẽ đã được xóa nhưng không. Không chắc chắn những gì cần tìm để tìm ra mục đích của tất cả.
JoeManiaci
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.