Is it possible to create a hard link to a file, using only Racket ?
I did try using (make-file-or-directory-link) but it only make symbolic link, not hard link. I'm working on *nix environment so, I could (system) to invoke a shell but I would prefer find an implementation on Racket only.
Thanks in advance.
All the filesystem stuff in Racket tries to be portable between Unixish systems and Windows, so there's no direct support for creating hard links (Which aren't supported by Windows AFAIK).
Here's a little module that uses the FFI to call the underlying link(2)
syscall to create a hard link that you can use:
#lang racket/base
(require ffi/unsafe ffi/unsafe/define (rename-in racket/contract [-> -->]))
(provide
(contract-out
[make-hard-link (--> path-string? path-string? boolean?)]))
(define-ffi-definer define-syscall (ffi-lib #f))
(define-syscall link (_fun #:save-errno 'posix _path _path -> _int))
(define (make-hard-link from to)
(define ret (link (path->complete-path from) (path->complete-path to)))
(cond
[(= ret 0) #t] ; success
[(= ret -1) ; error; raise an exception
(define errno (saved-errno))
(raise
(make-exn:fail:filesystem:errno
(format "make-hard-link: creating hard link failed;\n from: ~A\n to: ~A\n errno: ~A" from to errno)
(current-continuation-marks)
(cons errno 'posix)))]
[else ; shouldn't happen but catch just in case
(error 'make-hard-link "invalid return value from link(2) syscall: ~A" ret)]))