symlink readlink link建立、讀取,使用readlink獲取當前程式目錄
阿新 • • 發佈:2019-01-28
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;
}
標頭檔案: #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;
}