16 Temmuz 2018 Pazartesi

fcntl POSIX metodu

Giriş
Şu satırı dahil ederiz.
#include <fcntl.h>
fcntl ile ilgili aldığım bazı notlar aşağıda. fcntl bir POSIX metodu. Burada Posix standardı olan fcntl  ile Unix sistem çağrısı olan ioctl() arasındaki fark anlatılıyor.

fctnl ile dosyanın erişim durumunu almak
Buradaki örnekte gösterildiği gibi O_ACCMODE ile erişim durumu alınabilir.
int fd = fileno(f);
int accmode = fcntl(fd, F_GETFL) & O_ACCMODE;
Çıktı olarak O_RDONLY, O_WRONLY, veya O_RDWR gibi değerler alırız.

fctnl ile non-blocking mode'a geçmek
Örnek
Önce mevcut bitleri alırız.
int flags = fcntl(fd, F_GETFL);
Daha sonra O_NONBLOCK bayrağını kaldırırız.
fcntl(fd, F_SETFL, oldfl | O_NONBLOCK); 
Örnek
Aynı şeyi tek satırda şöyle yaparız.
fcntl(fd, F_SETFL, fcntl(sock_desc, F_GETFL, 0) | O_NONBLOCK);` 
Örnek
Mevcut bitlere dikkat etmeden sadece O_NONBLOCK biti de atanabilir ancak bence yapmamak lazım.
fcntl(fd, F_SETFL, O_NONBLOCK);
Örnek
timeout ile bağlanmak için şöyle yaparız.
typedef enum {
    e_resolve   = -1,
    e_socket    = -2,
    e_sockopt   = -3,
    e_parse     = -4,
    e_timeout   = -5,
    e_io        = -6
} Error;

int main(void) {
...

  sd = connect_to(host, atoi(port));
  ...
  close(sd);
  return 0;
}

int connect_to(char *host, int port) {
  int sd;
  struct sockaddr_in addr;
  fd_set sfds;
  struct timeval tv;

  sd = socket(AF_INET, SOCK_STREAM, 0);
  if (sd == -1) return e_socket;
  if (fcntl(sd, F_SETFL, O_NONBLOCK) == -1) return e_sockopt;
  memset(&addr, 0, sizeof (addr));
  addr.sin_family = AF_INET;
  if (inet_pton(AF_INET, host, &addr.sin_addr) != 1)
    return e_parse;
  addr.sin_port = htons(port);
  connect(sd, (struct sockaddr *) &addr, sizeof (addr));
  FD_ZERO(&sfds);
  FD_SET(sd, &sfds);
  tv.tv_sec = 4;
  tv.tv_usec = 0;
  if (select(sd + 1, NULL, &sfds, NULL, &tv)) return sd;
    return e_timeout;
}
fctnl ile non-blocking mode'dan çıkmak
Şöyle yaparız.
int flags = fcntl(sockfd, F_GETFL);
fcntl(sockfd, F_SETFL, flags & ~O_NONBLOCK);
fcntl ile dosya kilitleme
flock ile de dosya kilitlemek mümkün. Açıklaması şöyle
The l_type field can be used to place a read (F_RDLCK) or a write (F_WRLCK) lock on a file. Any number of processes may hold a read lock (shared lock) on a file region, but only one process may hold a write lock (exclusive lock). An exclusive lock excludes all other locks, both shared and exclusive.
Bu konu için Dosya İşlemleri başlıklı yazıya göz atabilirsiniz.

Hiç yorum yok:

Yorum Gönder