⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sysdep.c

📁 支持网络和单机的麻将游戏
💻 C
📖 第 1 页 / 共 2 页
字号:
  } else {    return closesocket(s);  }}/* read a line, up to lf/crlf terminator, from the socket,   and return it.   Internal backslashes are removed, unless doubled.   If the line ends with an unescaped backslash, replace by newline,   and append the next line.   If there is an error or end of file before seeing a terminator,   NULL is returned. At present, error includes reading a partial line.   The returned string is valid until the next call of get_line.   This is the internal function implementing the next two;   the second arg says whether the first is int or SOCKET.*/static char *_get_line(int fd,int is_socket) {  int length,i,j;  int offset=0;  static char *buffer = NULL;  static size_t buffer_size = 0;  while ( 1 ) {    while ( 1 ) {      while (offset+1 >= (int)buffer_size) { /* +1 to keep some space for '\0' */	buffer_size = (buffer_size == 0) ? 1024 : (2 * buffer_size);	buffer = realloc(buffer, buffer_size);	if (!buffer) {	  perror("get_line");	  exit(-1);	}      }      length = (is_socket ?	(skt_reader ? skt_reader((void *)fd,buffer+offset,1)		  : #ifdef WIN32		  recv(fd,buffer+offset,1,0)#else		  read(fd,buffer+offset,1)#endif	 ) : read(fd,buffer+offset,1));      if ((length <= 0) || (buffer[offset] == '\n'))	break;      offset += length;    }    if ( offset == 0 ) return NULL;    if ( length <= 0 ) {      fprintf(stderr,"get_line read partial line");      return NULL;    }    offset += length;    buffer[offset] = '\0';    /* now check for newline */    if ( buffer[offset-1] == '\n' ) {      if ( buffer[offset-2] == '\r' && buffer[offset-3] == '\\' ) {        /* zap the CR */	buffer[offset-2] = '\n';	buffer[offset-1] = '\0';	offset -= 1;        /* and go onto next clause */      }      if ( buffer[offset-2] == '\\' ) {	/* we have to decide whether this is an escaped backslash */	int j = 1,k=offset-3;	while ( k >= 0 && buffer[k--] == '\\' ) j++;	if ( j & 1 ) {	  /* odd number, not escaped */	  buffer[offset-2] = '\n' ;	  buffer[--offset] = '\0' ;	  /* read another line */	} else break; /* return this line */      } else break; /* return this line */    } /* no newline, keep going */  }  /* now remove internal backslashes */  for ( i = j = 0; 1; i++, j++ ) {    if ( buffer[j] == '\\' ) {      j++;    }    buffer[i] = buffer[j];    if ( !buffer[i] ) break;  }  return buffer;}char *get_line(SOCKET fd) {  /* are we actually being asked to read from stdout? Then read     from stdin */  if ( fd == STDOUT_FILENO ) return _get_line(STDIN_FILENO,0);  return _get_line((int)fd,1);}char *fd_get_line(int fd) {  return _get_line(fd,0);}static int _put_line_aux(int fd, char* line, int length, int is_socket) {  int n;  if ( is_socket ) {    n = skt_writer ? skt_writer((void *)fd,line,length)      :#ifdef WIN32      send(fd,line,length,0)#else      write(fd,line,length)#endif      ;  } else {    n = write(fd,line,length);  }  if ( n < length ) {    perror("put_line: write failed");    return -1;  }  return n;}/* write a line (which is assumed to have any terminator included)   to the given socket. Return -1 on error, length of line on success.   Replace internal newlines by backslash CRLF and write as lines.   Double all internal backslashes.   Third arg says whether first arg is really an int, or a SOCKET.   This is the internal function implemented the next two.*/static int _put_line(int fd,char *line,int is_socket) {  int length,n;  static char *buffer = NULL;  static size_t buf_size = 0;  int i,j;  /* the backslash/newline escaping can at worst treble the size     of the input */  length = strlen(line) + 1; /* include null */  while ( (int)buf_size <= 3*length ) {    buf_size = buf_size ? 2*buf_size : 1024;    buffer = realloc(buffer,buf_size);  }  /* FIXME: should retry if only write partial line */  i = j = 0;  while ( *line ) {    if ( *line == '\\' ) { buffer[i++] = '\\' ; }    if ( *line == '\n' && *(line+1) ) {      buffer[i++] = '\\' ;      buffer[i++] = '\r' ;      buffer[i++] = *(line++) ;      n = _put_line_aux(fd,buffer,i,is_socket);      if ( n < 0 ) { return -1 ; }      i = 0;    } else {      buffer[i++] = *(line++);    }  }  return _put_line_aux(fd,buffer,i,is_socket);}int put_line(SOCKET fd,char *line) {  /* are we asked to write to stdout? */  if ( fd == STDOUT_FILENO ) return _put_line(STDOUT_FILENO,line,0);  return _put_line((int)fd,line,1);}int fd_put_line(int fd,char *line) {  return _put_line(fd,line,0);}/* random integer from 0 to top inclusive */static int seed = 0;unsigned int rand_index(int top) {  if ( seed == 0 ) {    /* seed the generator */    rand_seed(0);  }  return (unsigned int)((1.0+top)*rand()/(RAND_MAX+1.0));}/* and seed it */void rand_seed(int s) {  if ( s == 0 ) s = time(NULL);  srand(seed = s);}/* feed a command to the system to be started in background.   No fancy argument processing, just pass to shell or equiv.   Return 1 on success, 0 on failure. */int start_background_program(const char *cmd) {  char buf[1024];# ifdef WIN32  int res;  STARTUPINFO si;  PROCESS_INFORMATION pi;    strncpy(buf,cmd,1023); buf[1023] = 0;  memset((void *)&si,0,sizeof(STARTUPINFO));  si.cb = sizeof(STARTUPINFO);  res = CreateProcess(NULL,buf,NULL,NULL,		0,DETACHED_PROCESS,NULL,NULL,&si,&pi);  if ( res ) {    CloseHandle(pi.hProcess);    CloseHandle(pi.hThread);  } else {    warn("Failed to start process %s",cmd);  }  return res;# else  strcpy(buf,cmd);  strcat(buf," &");# endif  return ! system(buf);}/* unfortunately we need a slightly more sophisticated one where   we can get at the output. This passes out a write handle for the   new process's stdin, and a read handle for its stdout */#ifndef WIN32int start_background_program_with_io(const char *cmd,int *childin,  int *childout){  int tochild[2], fromchild[2];  int cpid;    if ( pipe(tochild) < 0 ) {    perror("Unable to create pipe");    return 0;  }  if ( pipe(fromchild) < 0 ) {    perror("Unable to create pipe: %s");    return 0;  }  cpid = fork();  if ( cpid < 0 ) {    perror("Unable to fork: %s");  }  if ( cpid ) {    /* parent */    close(tochild[0]);    close(fromchild[1]);    *childin = tochild[1];    *childout = fromchild[0];    return 1;  } else {    close(tochild[1]);    close(fromchild[0]);    dup2(tochild[0],0);    close(tochild[0]);    dup2(fromchild[1],1);    close(fromchild[1]);    execl("/bin/sh","sh","-c",cmd,NULL);    /* what can we do if we get here? Not a lot... */    perror("Exec of child failed");    exit(1);  }  return 0;}#else/* This windows version is loosely based on the example   Creating a Child Process with Redirected Input and Output   from the MSDN Library. See that example for all the comments   explaining what's going on.    In fact it's (a) easier than that, since instead of saving, setting   and inheriting handles, we can put the pipes into the startup   info of the CreateProcess call. (Thanks to somebody on Usenet,   no thanks to Microsoft!); (b) harder, because we need to pass   back C-style file descriptors, not Windows handles. Hence the mystic   call to _open_osfhandle. */int start_background_program_with_io(const char *cmd,int *childin,  int *childout){  int res;  char buf[1024];  STARTUPINFO si;  PROCESS_INFORMATION pi;  SECURITY_ATTRIBUTES sa;  HANDLE tochildr, tochildw, tochildw2,     fromchildr, fromchildr2, fromchildw;    sa.nLength = sizeof(SECURITY_ATTRIBUTES);  sa.bInheritHandle = TRUE;  sa.lpSecurityDescriptor = NULL;  if ( ! CreatePipe(&fromchildr,&fromchildw,&sa,0 ) ) {    perror("couldn't create pipe");    return 0;  }  DuplicateHandle(GetCurrentProcess(),    fromchildr,GetCurrentProcess(),&fromchildr2,0,    FALSE, DUPLICATE_SAME_ACCESS);  CloseHandle(fromchildr);  if ( ! CreatePipe(&tochildr,&tochildw,&sa,0 ) ) {    perror("couldn't create pipe");    return 0;  }  DuplicateHandle(GetCurrentProcess(),    tochildw,GetCurrentProcess(),&tochildw2,0,    FALSE, DUPLICATE_SAME_ACCESS);  CloseHandle(tochildw);  strncpy(buf,cmd,1023); buf[1023] = 0;  memset((void *)&si,0,sizeof(STARTUPINFO));  si.cb = sizeof(STARTUPINFO);  si.dwFlags = STARTF_USESTDHANDLES;  si.hStdOutput = fromchildw;                si.hStdInput  = tochildr;             si.hStdError  = 0;  res = CreateProcess(NULL,buf,NULL,NULL,		TRUE,DETACHED_PROCESS,NULL,NULL,&si,&pi);  if ( res ) {    CloseHandle(pi.hProcess);    CloseHandle(pi.hThread);  } else {    warn("Failed to start process %s",cmd);  }  /* I think the mingw has the wrong type for _open_osfhandle ? */  *childin = _open_osfhandle((int)tochildw2,_O_WRONLY);  *childout = _open_osfhandle((int)fromchildr2,_O_RDONLY);  /* do we, as in unix, close our versions of the handles we don't want? */  if ( 1 ) {    CloseHandle(tochildr);    CloseHandle(fromchildw);  }  return res;}#endif/* return a home directory */char *get_homedir(void) {  char *p;# ifdef WIN32  static char buf[512];  buf[0] = 0;  if ( (p = getenv("HOMEDRIVE")) ) strcpy(buf,p);  if ( (p = getenv("HOMEPATH")) ) strcat(buf,p);  if ( buf[0] ) return buf;  return NULL;# else  struct passwd *pw;  if ( (p = getenv("HOME")) ) return p;  if ( (pw = getpwuid(getuid())) ) return pw->pw_dir;  return NULL;# endif}/* stuff for Windows */#ifdef WIN32int gettimeofday(struct timeval *tv, void *tz UNUSED) {  long sec, usec;  LONGLONG ll;  FILETIME ft;  GetSystemTimeAsFileTime(&ft);  ll = ft.dwHighDateTime;  ll <<= 32;  ll |= ft.dwLowDateTime;  /* this magic number comes from Microsoft's knowledge base ' */  ll -= 116447360000000000;  /* 100 nanoseconds since 1970 */  ll /= 10; /* microseconds since 1970 */  sec = (long)(ll / 1000000);  usec = (long)(ll - 1000000*((LONGLONG) sec));  if ( tv ) {    tv->tv_sec = sec;    tv->tv_usec = usec;  }  return 0;}char *getlogin(void) {   static char buf[128];  DWORD len = 128;  buf[0] = 0;  GetUserName(buf,&len);  return buf;} int getpid(void) {  return GetCurrentProcessId();}int unlink(const char *f) {  return DeleteFile(f); }unsigned int sleep(unsigned int t) { Sleep(1000*t); return 0; }/* I don't think we really need submillisecond resolution ... */unsigned int usleep(unsigned int t) { Sleep(t/1000); return 0; }/* fake (v)snprintf, by just ignoring the size argument */int vsnprintf(char *str, size_t size, const char *format, va_list ap) {  if ( size == 0 ) return 0;  return vsprintf(str,format,ap);}int snprintf(char *str, size_t size, const char *format, ...) {  int n;  va_list args;  va_start(args,format);  if ( size == 0 ) return 0;  n = vsprintf(str,format,args);  va_end(args);  return n;}#endif /* WIN32 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -