/* * This code is public domain sample code. * Written by Manfred Spraul, 1999 * * The application must be started by root or * setuid(root). * * $Header: /pub/cvs/ms/ipcmsg/longqueue.c,v 1.2 1999/10/09 23:27:54 manfreds Exp $ */ #include #include #include #include /* result codes: * 0: success * 1: partial success, queue len now USHORT_MAX * 100: invalid parameters. * 101: other error * 256: fatal error, please delete the queue: queue len now 0. */ #define USHORT_MAX 0xFFff struct queuelen { int llen; unsigned short slen; }; struct msqid_ds g_q; #define msg_lqbytes __rwait void failure(char* msg) { printf(" unexpected error in %s.\n",msg); exit(101); } int init_ipc(int id) { int res; res = msgget(id,0); if(res == -1) failure("findkey()"); id = res; res = msgctl(id,IPC_STAT,&g_q); if(res == -1) failure("init_ipc()"); return id; } void get_queuelen(int id, struct queuelen *out) { int res; struct msqid_ds q; res = msgctl(id,IPC_STAT,&q); if(res == -1) failure("get_queuelen()"); out->llen = q.msg_lqbytes; out->slen = q.msg_qbytes; } int set_queuelen(int id, int len) { struct msqid_ds q; memcpy(&q,&g_q,sizeof(q)); if(len > USHORT_MAX) { q.msg_qbytes = 0; q.msg_lqbytes = len; } else { q.msg_qbytes = len; } return msgctl(id,IPC_SET,&q); } int main(int argc,char** argv) { int id; int len; struct queuelen prev; struct queuelen new; printf("longqueue \n"); if(argc != 3) { printf("Invalid parameters.\n"); return 100; } id = atoi(argv[1]); len = atoi(argv[2]); if(len <= 0) { printf("Invalid parameters.\n"); return 100; } id = init_ipc(id); get_queuelen(id,&prev); if(set_queuelen(id,len) == -1) failure("set_queuelen()"); if(len <= USHORT_MAX) { out_success: get_queuelen(id,&prev); printf(" new queuelen: (%d,%d).\n",prev.slen,prev.llen); return 0; } /* the old Linux ipcmsg code doesn't support * long queues. It interprets this as "queue len 0". * Check for this, and try USHORT_MAX, then the original * value. */ get_queuelen(id,&new); if(new.slen != 0) goto out_success; if(set_queuelen(id,USHORT_MAX) == -1) { if(set_queuelen(id,prev.slen) == -1) { printf(" fatal error. queue len now 0.\n"); return 256; }; failure("set_queuelen()"); } get_queuelen(id,&new); printf(" new queuelen: (%d,%d).\n",prev.slen,prev.llen); return 1; }