我创建了一个程序,通过作为参数传递的 shmid(共享内存 id)显示共享内存段信息。
将数据与命令 ipcs 返回的数据进行比较,很明显我的程序显示了一些关于共享内存段的错误信息。
你能帮我理解为什么吗?
谢谢你。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <time.h>
#include <errno.h>
struct shmem_info {
int id;
struct shmid_ds data;
};
int *allocate_int(int n) {
int *mem;
if((mem=malloc(n*sizeof(int)))==NULL) {
perror("malloc");
exit(EXIT_FAILURE);
}
return mem;
}
struct shmem_info *allocate_shminfo(int n) {
struct shmem_info *mem;
if((mem=malloc(n*sizeof(struct shmem_info)))==NULL) {
perror("malloc");
exit(EXIT_FAILURE);
}
return mem;
}
int parse_int(char *str) {
int n;
n=atoi(str);
return n;
}
int open_fileRW(char *path) {
int fd;
if((fd=open(path,O_RDWR|O_CREAT,0666))==-1) {
perror("open");
exit(EXIT_FAILURE);
}
return fd;
}
void close_file(int fd) {
if(close(fd)==-1) {
perror("close");
exit(EXIT_FAILURE);
}
}
struct shmid_ds get_shminfo(int id) {
struct shmid_ds data;
errno=0;
if(shmctl(id,IPC_STAT,&data)==-1) {
switch(errno) {
case EACCES:
fprintf(stderr,"Shmid %d: read acces not allowed\n", id);
exit(EXIT_FAILURE);
case EINVAL:
fprintf(stderr,"Shmid %d: invalid shmid\n", id);
exit(EXIT_FAILURE);
default:
perror("shmctl");
exit(EXIT_FAILURE);
break;
}
}
return data;
}
void write_shminfo(int fd, struct shmem_info shmi) {
ssize_t w, tot=0, size=sizeof(struct shmem_info);
for(;;) {
errno=0;
w=write(fd,&shmi,size-tot);
if(w==-1 && errno!=EINTR) {
perror("write");
exit(EXIT_FAILURE);
}
if(w==0) return;
tot+=w;
}
}
struct shmem_info read_shminfo(int fd) {
ssize_t r, tot=0, size=sizeof(struct shmem_info);
struct shmem_info shmi;
for(;;) {
errno=0;
r=read(fd,&shmi,size-tot);
if(r==-1 && errno!=EINTR) {
perror("write");
exit(EXIT_FAILURE);
}
if(r==0) return shmi;
tot+=r;
}
}
void print_shminfo(FILE *out, struct shmem_info shmi) {
fprintf(out,"Shmid: %d\n", shmi.id);
fprintf(out,"Size of segment (bytes): %d\n", (int)shmi.data.shm_segsz);
fprintf(out,"PID of creator: %d\n", (int)shmi.data.shm_cpid);
fprintf(out,"No. of current attaches: %d\n", (int)shmi.data.shm_nattch);
fprintf(out,"Last attach time: %ld\n", shmi.data.shm_atime);
fprintf(out,"Last detach time: %ld\n", shmi.data.shm_dtime);
fprintf(out,"Last change time: %ld\n", shmi.data.shm_ctime);
fprintf(out,"PID of last shmat/shmdt: %d\n", (int)shmi.data.shm_lpid);
fprintf(out,"Key supplied to shmget(2): %d\n", (int)shmi.data.shm_perm.__key);
fprintf(out,"Effective UID of owner: %d\n", (int)shmi.data.shm_perm.uid);
fprintf(out,"Effective GID of owner: %d\n", (int)shmi.data.shm_perm.gid);
fprintf(out,"Effective UID of creator: %d\n", (int)shmi.data.shm_perm.cuid);
fprintf(out,"Effective GID of creator: %d\n", (int)shmi.data.shm_perm.cgid);
fprintf(out,"Permissions + SHM_DEST and ESHM_LOCKED flag: %hd\n", shmi.data.shm_perm.mode);
fprintf(out,"Sequence number: %hd\n", shmi.data.shm_perm.__seq);
fprintf(out,"\n");
}
int main(int argc, char *argv[]) {
int fd, n, i;
struct shmem_info *shmi;
if(argc<2) {
fprintf(stderr,"Usage: %s <shmid> <shmid> ... <shmid>\n", argv[0]);
exit(EXIT_FAILURE);
}
n=argc-1;
argv=argv+1;
shmi=allocate_shminfo(n);
for(i=0;i<n;i++) {
shmi[i].id=parse_int(argv[i]);
}
for(i=0;i<n;i++) {
shmi[i].data=get_shminfo(shmi[i].id);
}
fd=open_fileRW("shmid_info-log.txt");
for(i=0;i<n;i++) {
write_shminfo(fd,shmi[i]);
}
for(i=0;i<n;i++) {
shmi[i]=read_shminfo(fd);
}
for(i=0;i<n;i++) {
print_shminfo(stdout,shmi[i]);
}
close_file(fd);
free(shmi);
exit(EXIT_SUCCESS);
}