|
rllib
1
|
00001 /*************************************************************************** 00002 rlmailbox.cpp - description 00003 ------------------- 00004 begin : Tue Jan 02 2001 00005 copyright : (C) 2001 by Rainer Lehrig 00006 email : lehrig@t-online.de 00007 ***************************************************************************/ 00008 00009 /*************************************************************************** 00010 * * 00011 * This library is free software; you can redistribute it and/or modify * 00012 * it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as * 00013 * published by the Free Software Foundation * 00014 * * 00015 ***************************************************************************/ 00016 #include "rldefine.h" 00017 #include <stdio.h> 00018 #include <stdarg.h> 00019 #include <stdlib.h> 00020 #include <string.h> 00021 #ifndef RLWIN32 00022 #include <unistd.h> 00023 #endif 00024 #include "rlmailbox.h" 00025 #include "rlcutil.h" 00026 00027 #ifdef RLUNIX 00028 #include <fcntl.h> 00029 #include <sys/stat.h> 00030 #include <sys/types.h> 00031 #include <sys/ipc.h> 00032 #include <sys/msg.h> 00033 #endif 00034 00035 #ifdef __VMS 00036 #include <lib$routines.h> 00037 #include <libdef.h> 00038 #include <dvidef.h> 00039 #include <ssdef.h> 00040 #include <iodef.h> 00041 #include <descrip.h> 00042 #include <starlet.h> 00043 typedef struct 00044 { 00045 short iostat; 00046 unsigned short msg_len; 00047 int reader_pid; 00048 }IOSB; 00049 #endif 00050 00051 #ifdef RLWIN32 00052 #include <windows.h> 00053 #endif 00054 00055 rlMailbox::rlMailbox(const char *mbxname) 00056 { 00057 #ifdef RLUNIX 00058 FILE *fp; 00059 key_t key; 00060 00061 status = OK; 00062 name = new char[strlen(mbxname)+1]; 00063 strcpy(name,mbxname); 00064 // create file 00065 fp = fopen(name,"r"); 00066 if(fp == NULL) 00067 { 00068 fp = fopen(name,"w"); 00069 if(fp == NULL) 00070 { 00071 int ret; 00072 char buf[1024]; 00073 sprintf(buf,"could not write mailbox=%s\n",mbxname); 00074 ret = ::write(1,buf,strlen(buf)); 00075 if(ret < 0) exit(-1); 00076 sprintf(buf,"you have to run this program as root !!!\n"); 00077 ret = ::write(1,buf,strlen(buf)); 00078 if(ret < 0) exit(-1); 00079 exit(-1); 00080 } 00081 fchmod(fileno(fp),0x0fff); 00082 if(fp == NULL) { status=COULD_NOT_CREATE_MAILBOX; return; } 00083 } 00084 fclose(fp); 00085 // getkey 00086 00087 // old stuff, without suggestions from Stefan Lievens 00088 // key = ftok(name, 'R'); 00089 00090 key = ftok(name, 'b'); 00091 if(key == ((key_t) (-1))) { status=COULD_NOT_GET_KEY; return; } 00092 // get chanid 00093 00094 // old stuff, without suggestions from Stefan Lievens 00095 // chanid = msgget(key,IPC_CREAT); 00096 chanid = msgget(key, 0600 | IPC_CREAT); 00097 if(chanid == -1) { status=COULD_NOT_GET_CHAN_ID; return; } 00098 #endif 00099 00100 #ifdef __VMS 00101 long ret; 00102 short chan_id; 00103 struct dsc$descriptor_s dmbxname; 00104 00105 chanid = -1; 00106 status = OK; 00107 name = new char[strlen(mbxname)+1]; 00108 strcpy(name,mbxname); 00109 dmbxname.dsc$w_length = strlen(name); 00110 dmbxname.dsc$a_pointer = name; 00111 dmbxname.dsc$b_dtype = DSC$K_DTYPE_T; 00112 dmbxname.dsc$b_class = DSC$K_CLASS_S; 00113 ret = sys$crembx((char)1, // 0 temp 1 permanence flag 00114 &chan_id, // i/o channel 00115 MAX_MAILBOX, // max msg length 00116 MAX_MAILBOX*4, // max buffer size 00117 (long)0, 00118 (long)0, 00119 &dmbxname); // mailbox name 00120 if(ret == SS$_NORMAL) { chanid = chan_id; return; } 00121 else { status = COULD_NOT_CREATE_MAILBOX; return; } 00122 #endif 00123 00124 #ifdef RLWIN32 00125 chanid = -1; 00126 status = OK; 00127 name = new char[strlen(mbxname)+1]; 00128 strcpy(name,mbxname); 00129 #endif 00130 } 00131 00132 rlMailbox::~rlMailbox() 00133 { 00134 delete [] name; 00135 if(chanid < 0) return; 00136 00137 #ifdef __VMS 00138 sys$dassgn((short)chanid); 00139 #endif 00140 00141 #ifdef RLWIN32 00142 CloseHandle((HANDLE) chanid); 00143 #endif 00144 } 00145 00146 int rlMailbox::write(const void *buf, int len) 00147 { 00148 status = OK; 00149 00150 #ifdef RLUNIX 00151 int retlen; 00152 unsigned char *message = new unsigned char [sizeof(long) + len]; 00153 long *lptr = (long *) message; 00154 *lptr = 1; // mtype 00155 memcpy(&message[sizeof(long)],buf,len); 00156 retlen = msgsnd(chanid,(struct msgbuf *) message, len, 0); 00157 delete [] message; 00158 return retlen; 00159 #endif 00160 00161 #ifdef __VMS 00162 int ret; 00163 IOSB iosb; 00164 ret = sys$qiow (0, 00165 (short) chanid, 00166 IO$_WRITEVBLK | IO$M_NOW | IO$M_NORSWAIT, 00167 &iosb, 00168 0,0, 00169 buf, 00170 len,0,0,0,0); 00171 len = iosb.msg_len; 00172 if (ret == SS$_MBFULL) return MAILBOX_FULL; 00173 else if(ret != SS$_NORMAL) return MAILBOX_ERROR; 00174 else return len; // Success 00175 #endif 00176 00177 #ifdef RLWIN32 00178 BOOL bret; 00179 unsigned long numWritten; 00180 00181 if(chanid == -1) 00182 { 00183 HANDLE h; 00184 char mbxname[1024]; 00185 strcpy(mbxname,"\\\\.\\mailslot\\"); strcat(mbxname,name); 00186 h = CreateFile( 00187 mbxname, // pointer to name of the file 00188 GENERIC_READ | GENERIC_WRITE, // access (read-write) mode 00189 FILE_SHARE_READ | FILE_SHARE_WRITE, // share mode 00190 NULL, // pointer to security attributes 00191 OPEN_EXISTING, // how to create 00192 FILE_ATTRIBUTE_NORMAL, // file attributes 00193 NULL // handle to file with attributes to copy 00194 ); 00195 if(h == INVALID_HANDLE_VALUE) 00196 { 00197 status = GetLastError(); 00198 return MAILBOX_ERROR; 00199 } 00200 chanid = (int) h; 00201 } 00202 00203 bret = WriteFile( 00204 (HANDLE) chanid, // handle to file to write to 00205 buf, // pointer to data to write to file 00206 len, // number of bytes to write 00207 &numWritten, // pointer to number of bytes written 00208 NULL // pointer to structure for overlapped I/O 00209 ); 00210 if(bret==0) 00211 { 00212 status = GetLastError(); 00213 CloseHandle((HANDLE) chanid); 00214 chanid = -1; 00215 return MAILBOX_ERROR; 00216 } 00217 return numWritten; 00218 #endif 00219 } 00220 00221 int rlMailbox::read(void *buf, int maxlen, int wait) 00222 { 00223 char *cbuf; 00224 status = OK; 00225 cbuf = (char *) buf; 00226 00227 #ifdef RLUNIX 00228 int len; 00229 unsigned char *message = new unsigned char [sizeof(long) + maxlen]; 00230 if(wait == WAIT ) len = msgrcv(chanid,(struct msgbuf *) message, maxlen,0,0); 00231 else len = msgrcv(chanid,(struct msgbuf *) message, maxlen,0,IPC_NOWAIT); 00232 if(len < maxlen && len >= 0) 00233 { 00234 memcpy(buf,&message[sizeof(long)],len); 00235 cbuf[len] = '\0'; 00236 } 00237 else 00238 { 00239 cbuf[0] = '\0'; 00240 } 00241 delete [] message; 00242 return len; 00243 #endif 00244 00245 #ifdef __VMS 00246 int ret,len; 00247 IOSB iosb; 00248 if(wait == NOWAIT) 00249 { 00250 ret = sys$qiow(0, 00251 (short) chanid, 00252 IO$_READVBLK | IO$M_NOW, // I/O CODE 00253 &iosb, 00254 0,0, 00255 buf, 00256 maxlen,0,0,0,0); 00257 } 00258 else 00259 { 00260 ret = sys$qiow(0, 00261 (short) chanid, 00262 IO$_READVBLK, // I/O CODE 00263 &iosb, 00264 0,0, 00265 buf, 00266 maxlen,0,0,0,0); 00267 } 00268 len = (int) iosb.msg_len; 00269 if(len < maxlen && len >= 0) cbuf[len] = '\0'; 00270 if (ret == SS$_NORMAL && iosb.iostat == SS$_NORMAL) return len; 00271 else if(iosb.iostat == SS$_NORMAL) { status = -1; return MAILBOX_ERROR; } 00272 else if(ret == SS$_NORMAL) 00273 { 00274 if(wait == NOWAIT && iosb.iostat == SS$_ENDOFFILE) { status = -2; return MAILBOX_ERROR; } 00275 else { status = -3; return MAILBOX_ERROR; } 00276 } 00277 status = -4; return MAILBOX_ERROR; 00278 #endif 00279 00280 #ifdef RLWIN32 00281 HANDLE h; 00282 char mbxname[1024]; 00283 unsigned long lenRead; 00284 BOOL bret,bret2; 00285 00286 if(chanid == -1) 00287 { 00288 strcpy(mbxname,"\\\\.\\mailslot\\"); strcat(mbxname,name); 00289 h = CreateMailslot( 00290 mbxname, // pointer to string for mailslot name 00291 MAX_MAILBOX, // maximum message size 00292 MAILSLOT_WAIT_FOREVER, // milliseconds before read time-out 00293 NULL); // pointer to security structure 00294 if(h == INVALID_HANDLE_VALUE) { status = GetLastError(); return MAILBOX_ERROR; } 00295 chanid = (int) h; 00296 00297 bret2 = SetMailslotInfo((HANDLE) chanid, MAILSLOT_WAIT_FOREVER); 00298 if(bret2 == 0) { status = GetLastError(); return MAILBOX_ERROR; } 00299 } 00300 00301 if(wait == NOWAIT) // begin wait 00302 { 00303 lenRead = 0; 00304 bret2 = SetMailslotInfo((HANDLE) chanid, 0); 00305 if(bret2 == 0) { status = GetLastError(); return MAILBOX_ERROR; } 00306 bret = ReadFile( 00307 (HANDLE) chanid, // handle of file to read 00308 buf, // pointer to buffer 00309 maxlen, // number of bytes to read 00310 &lenRead, // pointer to number of bytes read 00311 NULL // pointer to structure for data 00312 ); 00313 bret2 = SetMailslotInfo((HANDLE) chanid, MAILSLOT_WAIT_FOREVER); 00314 if(bret2 == 0) { status = GetLastError(); return MAILBOX_ERROR; } 00315 if(bret == 0) { status = GetLastError(); return MAILBOX_ERROR; } 00316 if((int) lenRead < maxlen && (int) lenRead >= 0) cbuf[lenRead] = '\0'; 00317 return lenRead; 00318 } // end wait 00319 00320 lenRead = 0; 00321 bret = ReadFile( 00322 (HANDLE) chanid, // handle of file to read 00323 buf, // pointer to buffer 00324 maxlen, // number of bytes to read 00325 &lenRead, // pointer to number of bytes read 00326 NULL // pointer to structure for data 00327 ); 00328 if(bret == 0) { status = GetLastError(); return MAILBOX_ERROR; } 00329 if((int) lenRead < maxlen && (int) lenRead >= 0) cbuf[lenRead] = '\0'; 00330 return lenRead; 00331 #endif 00332 } 00333 00334 void rlMailbox::clear() 00335 { 00336 char *buf = new char[MAX_MAILBOX]; 00337 while(read(buf,MAX_MAILBOX,NOWAIT) > 0); 00338 delete [] buf; 00339 } 00340 00341 int rlMailbox::printf(const char *format, ...) 00342 { 00343 int ret; 00344 char message[rl_PRINTF_LENGTH]; // should be big enough 00345 00346 va_list ap; 00347 va_start(ap,format); 00348 ret = rlvsnprintf(message, rl_PRINTF_LENGTH - 1, format, ap); 00349 va_end(ap); 00350 if(ret < 0) return ret; 00351 return write(message,strlen(message)); 00352 }
1.7.5.1