1 /* 2 * Copyright (c) 2017 Xiao yang <yangx.jy (at) cn.fujitsu.com> 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #include <sys/types.h> 19 #include <sys/ipc.h> 20 #include <sys/msg.h> 21 #include <sys/shm.h> 22 #define TST_NO_DEFAULT_MAIN 23 #include "tst_test.h" 24 #include "tst_safe_sysv_ipc.h" 25 26 /* 27 * The IPC_STAT, IPC_SET and IPC_RMID can return either 0 or -1. 28 * 29 * Linux specific cmds either returns -1 on failure or positive integer 30 * either index into an kernel array or shared primitive indentifier. 31 */ 32 static int ret_check(int cmd, int ret) 33 { 34 switch (cmd) { 35 case IPC_STAT: 36 case IPC_SET: 37 case IPC_RMID: 38 return ret != 0; 39 default: 40 return ret == -1; 41 } 42 } 43 44 int safe_msgget(const char *file, const int lineno, key_t key, int msgflg) 45 { 46 int rval; 47 48 rval = msgget(key, msgflg); 49 if (rval == -1) { 50 tst_brk(TBROK | TERRNO, "%s:%d: msgget(%i, %x) failed", 51 file, lineno, (int)key, msgflg); 52 } 53 54 return rval; 55 } 56 57 int safe_msgsnd(const char *file, const int lineno, int msqid, const void *msgp, 58 size_t msgsz, int msgflg) 59 { 60 int rval; 61 62 rval = msgsnd(msqid, msgp, msgsz, msgflg); 63 if (rval == -1) { 64 tst_brk(TBROK | TERRNO, 65 "%s:%d: msgsnd(%i, %p, %zu, %x) failed", 66 file, lineno, msqid, msgp, msgsz, msgflg); 67 } 68 69 return rval; 70 } 71 72 ssize_t safe_msgrcv(const char *file, const int lineno, int msqid, void *msgp, 73 size_t msgsz, long msgtyp, int msgflg) 74 { 75 ssize_t rval; 76 77 rval = msgrcv(msqid, msgp, msgsz, msgtyp, msgflg); 78 if (rval == -1) { 79 tst_brk(TBROK | TERRNO, 80 "%s:%d: msgrcv(%i, %p, %zu, %li, %x) failed", 81 file, lineno, msqid, msgp, msgsz, msgtyp, msgflg); 82 } 83 84 return rval; 85 } 86 87 int safe_msgctl(const char *file, const int lineno, int msqid, int cmd, 88 struct msqid_ds *buf) 89 { 90 int rval; 91 92 rval = msgctl(msqid, cmd, buf); 93 if (ret_check(cmd, rval)) { 94 tst_brk(TBROK | TERRNO, 95 "%s:%d: msgctl(%i, %i, %p) = %i failed", 96 file, lineno, msqid, cmd, buf, rval); 97 } 98 99 100 return rval; 101 } 102 103 int safe_shmget(const char *file, const int lineno, key_t key, size_t size, 104 int shmflg) 105 { 106 int rval; 107 108 rval = shmget(key, size, shmflg); 109 if (rval == -1) { 110 tst_brk(TBROK | TERRNO, "%s:%d: shmget(%i, %zu, %x) failed", 111 file, lineno, (int)key, size, shmflg); 112 } 113 114 return rval; 115 } 116 117 void *safe_shmat(const char *file, const int lineno, int shmid, 118 const void *shmaddr, int shmflg) 119 { 120 void *rval; 121 122 rval = shmat(shmid, shmaddr, shmflg); 123 if (rval == (void *)-1) { 124 tst_brk(TBROK | TERRNO, "%s:%d: shmat(%i, %p, %x) failed", 125 file, lineno, shmid, shmaddr, shmflg); 126 } 127 128 return rval; 129 } 130 131 int safe_shmdt(const char *file, const int lineno, const void *shmaddr) 132 { 133 int rval; 134 135 rval = shmdt(shmaddr); 136 if (rval == -1) { 137 tst_brk(TBROK | TERRNO, "%s:%d: shmdt(%p) failed", 138 file, lineno, shmaddr); 139 } 140 141 return rval; 142 } 143 144 int safe_shmctl(const char *file, const int lineno, int shmid, int cmd, 145 struct shmid_ds *buf) 146 { 147 int rval; 148 149 rval = shmctl(shmid, cmd, buf); 150 if (ret_check(cmd, rval)) { 151 tst_brk(TBROK | TERRNO, 152 "%s:%d: shmctl(%i, %i, %p) = %i failed", 153 file, lineno, shmid, cmd, buf, rval); 154 } 155 156 return rval; 157 } 158