第二个轮子OS API

OS API

在Linux应用编程中,常常为了获取或设置一些信息,写一些重复性的代码,在此整理一下,作为实现的第二个轮子,暂且称之为OS API

删除文件

1
2
3
4
int do_rm_file(char *file_name)
{
return unlink(file_name);
}

删除文件夹

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int unlink_cb(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf)
{
int rv = remove(fpath);
if (rv)
{
ALOGE("remove(%s) failed, rv: %d, err: %d\n", fpath, rv, errno);
}

return rv;
}

int do_rmdir(char *path)
{
int rv = nftw(path, unlink_cb, 64, FTW_DEPTH | FTW_PHYS);
if ((rv != 0) && (errno != ENOENT))
{
return -1;
}

return 0;
}

文件夹是否为空

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
int is_dirempty(char *dirname)
{
DIR *dir = opendir(dirname);
struct dirent *ent;
if (dir == NULL)
{
return -1;
}
while (1)
{
ent = readdir (dir);
if (ent <= 0)
{
break;
}
if ((strcmp(".", ent->d_name)==0) || (strcmp("..", ent->d_name)==0))
{
continue;
}
if ((ent->d_type == DT_DIR) || (ent->d_type == DT_REG))
{
closedir(dir);
return -1;
}
}
closedir(dir);
return 0;
}

执行shell命令并获取结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
int popen_read(char *cmd,char *res,int len)
{
len--;//预留一个位来保存'\0'
if(cmd == NULL || res == NULL)
return -1;
FILE *fp;
char buf[1024];
int l,nread = 0;
fp = popen(cmd,"r");
if(fp != NULL)
{
while(fgets(buf,1024,fp) != NULL)
{
l = strlen(buf);
if(l >= len - nread)
{
memcpy(res + nread,buf,len-nread);
res[len+1] = '\0';
return len;
}
else
{
memcpy(res + nread,buf,l+1);
}
nread += l;
}
pclose(fp);
return nread;
}
else
{
return -1;
}
}

执行多参数shell命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
int do_system(unsigned char wait, int *svc_pid, const char *exec_file, ...)
{
pid_t pid;
int status = -1;
int rc = -1;
sigset_t chldmask, savemask;
list<string>::iterator list_iterator;

if (exec_file == NULL)
{
return (-1);
}

/* now block SIGCHLD */
sigemptyset(&chldmask);
sigaddset(&chldmask, SIGCHLD);
if (sigprocmask(SIG_BLOCK, &chldmask, &savemask))
{
return (-2);
}

pid = fork();
if (pid < 0)
{
/* Error. */
rc = -3;
}
else if (pid == 0)
{
/* Child. */
int n = 0;
char **argv;
int argc = 0;
char **p;
va_list args;

ALOGI("exec_file[%d]:%s", getpid(), exec_file);

n = 1; /* =1 for argv[0]. */
va_start(args, exec_file);
for (; va_arg(args, char *);)
{
++n;
}
va_end(args);

p = argv = (char **)malloc((n + 1) * sizeof(char *)); /* +1 for terminal NULL */

p[0] = (char *)exec_file;

va_start(args, exec_file);
for (; n--;)
{
*++p = va_arg(args, char *);
}
va_end(args);
*p = NULL;

sigprocmask(SIG_SETMASK, &savemask, NULL);
n = execvp(exec_file, argv);
/* on error */
free(argv);
exit(n);
}
else
{
/* to make child run first. sleep 2ms. */
usleep(1 * 1000);
/* Parent. */
if (svc_pid)
{
*svc_pid = pid;
}

if (wait)
{
do
{
rc = waitpid(pid, &status, 0);
if (rc < 0)
{
if (errno != EINTR)
{
break;
}
}
else
{
rc = WEXITSTATUS(status);
break;
}
} while (1);
}
else
{
rc = 0;
}
}

sigprocmask(SIG_SETMASK, &savemask, NULL);
return rc;
}

删除字符串分隔符

1
2
3
4
5
6
7
8
9
10
11
12
13
void strdel(char *s, char del)
{
char *p;
char *q;
for (p=s, q=s; *p != '\0'; p++)
{
if (*p != del)
{
*q++ = *p;
}
}
*q=*p;
}

获取key和value

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//key=value
int strkv(char *src, char *key, char *value)
{
char *p, *q;
int len;
p = strchr(src, '=');
q = strchr(src, '\n');

if (p != NULL && q != NULL)
{
*q = '\0';
strncpy(key, src, p-src);
strcpy(value, p+1);
return 1;
}
return 0;
}

读取配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

struct configItem
{
char key[20];
char value[50];
};

void get_config(char * configFilePath, struct configItem* configVar, int configNum)
{
int i;
FILE * pfile;
char buf[50] = "";
char key[50] = "";
char value[50] = "";

pfile = fopen(configFilePath, "r");

if (pfile == NULL)
{
printf("配置文件打开失败!\n");
exit(-1);
}

memset(buf, 0, strlen(buf));
while (fgets(buf, 50, pfile))
{
memset(key, 0, strlen(key));
memset(value, 0, strlen(value));
if (strkv(buf, key, value)) //获取key和value
{
for (i = 0; i < configNum; i++)
{
if (strstr(key, configVar[i].key) != NULL)
{
strcpy(configVar[i].value, value);
}
}
}
else
{
printf("读取失败\n");
}
memset(buf, 0, strlen(buf));
}
fclose(pfile);
}

获取MAC地址

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
int get_if_macaddr(const char *name, char *macaddr)
{
int ret;
int rc;
int sockfd;
unsigned char mac[6];
struct ifreq ifr;

sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0) {
printf("socket() failed, err: %d,[%s]\n", errno, strerror(errno));
return -1;
}

snprintf(ifr.ifr_name, (sizeof(ifr.ifr_name) - 1), "%s", name);

rc = ioctl(sockfd, SIOCGIFFLAGS, &ifr);
if (rc < 0) {
printf("ioctl(%s, SIOCGIFFLAGS) failed, err: %d,[%s]\n", name, errno, strerror(errno));
ret = -1;
goto out;
}

rc = ioctl(sockfd, SIOCGIFHWADDR, &ifr);
if (rc < 0) {
printf("ioctl(%s, SIOCGIFHWADDR, %s) failed, err: %d,[%s]\n", name, macaddr, errno,
strerror(errno));
ret = -1;
goto out;
}

memcpy(mac, ifr.ifr_hwaddr.sa_data, sizeof(mac));
sprintf(macaddr, "%02X:%02X:%02X:%02X:%02X:%02X", (unsigned char)mac[0], (unsigned char)mac[1],
(unsigned char)mac[2], (unsigned char)mac[3], (unsigned char)mac[4], (unsigned char)mac[5]);
ret = 0;

out:
if (sockfd >= 0) {
close(sockfd);
}

return (ret);
}

监听子进程状态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//task = -1 监听所有子进程
int do_wait(int *task, int *status, int option)
{

pid_t pid;
int wait_status;

do
{
pid = waitpid(*task, &wait_status, option);
if (pid < 0)
{
if (errno != EINTR)
{
*task = pid;
return (-1);
}
usleep(1000);
continue;
}
} while (pid < 0);

if (task != NULL)
{
*task = pid;
}

if (status != NULL)
{
*status = wait_status;
}

return (0);
}

第二个轮子OS API
https://carl-5535.github.io/2022/01/23/造轮子/osapi/
作者
Carl Chen
发布于
2022年1月23日
许可协议