1. 程式人生 > >symlink readlink link建立、讀取,使用readlink獲取當前程式目錄

symlink readlink link建立、讀取,使用readlink獲取當前程式目錄

symlink 函式和 readlink 函式主要是針對符號連結檔案的操作。symlink 函式用來建立符號連結檔案,和 link 檔案是對應的。readlink 函式用來讀取連結檔案本身的內容(也就是符號連結指向的檔案的檔名)。


標頭檔案: #include <unistd.h>


函式原型:
int symlink(const char* actualpath,const char* sympath);
int symlinkat(const char *actualpath,int fd,const char *sympath);  
如果sympath引數指定的是絕對路徑或者fd引數設定了AT_FDCWD值,那麼symlinkat就等同於symlink函式。
函式引數:
oldpath:原始檔的路徑名
newpath:符號連結檔案的路徑名
返回值:
呼叫成功時返回 0
呼叫失敗時返回 -1
錯誤程式碼:
1、EPERM 引數actualpath 與sympath所指的檔案系統不支援符號連線。
2、EROFS 欲測試寫入許可權的檔案存在於只讀檔案系統內。
3、EFAULT 引數actualpath 或sympath 指標超出可存取記憶體空間。
4、ENAMETOOLONG 引數actualpath 或sympath 太長。
5、ENOMEM 核心記憶體不足。
6、EEXIST 引數newpath 所指的檔名已存在。
7、EMLINK 引數actualpath 所指的檔案已達到最大連線數目。
8、ELOOP 引數sympath 有過多符號連線問題。
9、ENOSPC 檔案系統的剩餘空間不足。
10、EIO I/O 存取錯誤。


定義函式:
int  readlink(const  char *path,  char *buf, size_t  bufsiz);
int  readlinkat(int fd,const char* path,char *buf,size_t bufsize);  
當pathname引數指定的是絕對路徑名或者fd引數的值為AT_FDCWD,readlinkat函式的行為與readlink相同。但是,如果fd引數是一個開啟目錄的有效檔案描述符並且pathname引數是相對路徑名,則readlinkat計算相對於由fd代表的開啟目錄的路徑。
這兩個函式組合了open、read和close的所有操作。如果函式成功執行,則返回讀入buf的位元組數。在buf中返回的符號連結的內容不以null字元終止。
函式引數;
path:讀取的符號連結檔案的路徑名
buf:用來儲存讀出的檔案內容
bufsiz:想要讀取的位元組數
返回值   :執行成功則傳符號連線所指的檔案路徑字串,失敗返回-1, 錯誤程式碼存於errno
錯誤程式碼:
               EACCESS                  取檔案時被拒絕,許可權不夠
               EINVAL                    引數bufsiz為負數
               EIO                         O存取錯誤
               ELOOP                     欲開啟的檔案有過多符號連線問題
               ENAMETOOLONG       引數path的路徑名稱太長
               ENOENT                   引數path所指定的檔案不存在
               ENOMEM                   核心記憶體不足
               ENOTDIR                   引數path路徑中的目錄存在但卻非真正的目錄




獲取當前exe的路徑
#include <stdio.h>
#include <unistd.h>
char * get_exe_path( char * buf, int count)
{
    int i;
    int rslt = readlink("/proc/self/exe", buf, count - 1);
    if (rslt < 0 || (rslt >= count - 1))
    {
        return NULL;
    }
    buf[rslt] = '\0';
    for (i = rslt; i >= 0; i--)
    {
        printf("buf[%d] %c\n", i, buf[i]);
        if (buf[i] == '/')
        {
            buf[i + 1] = '\0';
            break;
        }
    }
    return buf;
}


int main(int argc, char ** argv)
{
    char path[1024];
    printf("%s\n", get_exe_path(path, 1024));
    return 0;
}


symlinkat和readlinkat函式的例項程式如下:
#include <stdio.h>  
#include <unistd.h>  
#include <stdlib.h>  
#include <string.h>  
#include <errno.h>  
#include <sys/types.h>  
#include <dirent.h>  
#define BUFFSIZE 1024  
  
int main(int argc,char *argv[])  
{  
    if(argc != 4){  
        printf("param too few\n");  
        exit(EXIT_FAILURE);  
    }  
  
    char buf[BUFFSIZE];  
    ssize_t sz;  
    DIR *dp;  
    int fd;  
  
    //獲取相對路徑名返回的檔案描述符fd  
    if((dp = opendir(argv[2])) == NULL){  
        perror("opendir");  
        exit(EXIT_FAILURE);  
    }  
    if((fd = dirfd(dp)) < 0){  
        perror("dirfd");  
        exit(EXIT_FAILURE);  
    }  
  
    //建立符號連結  
    if(symlinkat(argv[1],fd,argv[3]) < 0){  
        perror("symlinkat");  
        exit(EXIT_FAILURE);  
    }  
  
    //讀取符號連結  
    memset(buf,0,sizeof(buf));  
    if((sz = readlinkat(fd,argv[3],buf,sizeof(buf))) < 0){  
        perror("readlinkat");  
        exit(EXIT_FAILURE);  
    }  
  
    printf("buf:%s,length:%u\n",buf,(unsigned int)sz);  
    close(fd);  
    return 0;  
}