sema.c
资源名称:socks5.zip [点击查看]
上传用户:sddyfurun
上传日期:2007-01-04
资源大小:525k
文件大小:5k
源码类别:
代理服务器
开发平台:
Unix_Linux
- /* Copyright (c) 1995,1996,1997 NEC Corporation. All rights reserved. */
- /* */
- /* The redistribution, use and modification in source or binary forms of */
- /* this software is subject to the conditions set forth in the copyright */
- /* document ("Copyright") included with this distribution. */
- /*
- * $Id: sema.c,v 1.20.4.1 1998/07/19 22:49:56 wlu Exp $
- */
- #include "socks5p.h"
- #include "sema.h"
- #include "log.h"
- #ifdef USE_SYSTEM_SEMAPHORE
- #ifdef HAVE_SYS_IPC_H
- #include <sys/ipc.h>
- #endif
- #ifdef HAVE_SYS_SEM_H
- #include <sys/sem.h>
- #endif
- int semacquire(void *sem) {
- struct sembuf sb = { 0, -1, SEM_UNDO };
- if (sem && semop(*(int *)sem, &sb, 1) < 0) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(0), 0, "Semacquire: semop failed: %m");
- return -1;
- }
- return 0;
- }
- int semrelease(void *sem) {
- struct sembuf sb = { 0, 1, SEM_UNDO };
- if (sem && semop(*(int *)sem, &sb, 1) < 0) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(0), 0, "Semrelease: semop failed: %m");
- return -1;
- }
- return 0;
- }
- int semreset(void *sem, int val) {
- /* I think semaphores with UNDO won't need resetting... */
- return 0;
- }
- void semdestroy(void *sem) {
- union { int val; struct semid_ds *buf; u_short *array; } u;
- u.val = 1;
- semctl(*(int *)sem, 0, IPC_RMID, u);
- }
- void *semcreate(int val) {
- int *semid = (int *)malloc(sizeof(int));
- union { int val; struct semid_ds *buf; u_short *array; } u;
- u.val = val;
- if (semid == NULL) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(0), 0, "Semcreate: malloc failed");
- return NULL;
- }
- if ((*semid = semget(IPC_PRIVATE, 1, 0666)) < 0) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(0), 0, "Semcreate: semget failed: %m");
- return NULL;
- }
- if (semctl(*semid, 0, SETVAL, u) < 0) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(0), 0, "Semcreate: semctl failed: %m");
- return NULL;
- }
- return (void *)semid;
- }
- #elif defined(USE_SEMAPHORES)
- #ifdef HAVE_SYS_IOCTL_H
- #include <sys/ioctl.h>
- #endif
- #ifdef HAVE_SYS_FILIO_H
- #include <sys/filio.h>
- #endif
- static int semstart(S5IOHandle *fd, int count) {
- if (pipe(fd) < 0) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(0), 0, "Semstart: pipe failed: %m");
- return -1;
- }
- while (count-- > 0) semrelease((void *)fd);
- return 0;
- }
- /* Lock (using the semaphore pipe, semfd) control of the signaling and pipes */
- /* (pipe reads and writes are atomic, so the pipe can act as a semaphore.) */
- int semacquire(void *sem) {
- S5IOHandle *fd = (int *)sem;
- char c;
- if (sem && RECVSOCKET(fd[0], &c, 1, 0) < 0) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(0), 0, "Semacquire: read failed: %m");
- return -1;
- }
- return 0;
- }
- /* Unlock (using the semaphore pipe) control of the signaling and pipes */
- /* (pipe reads and writes are atomic, so the pipe can act as a semaphore.) */
- int semrelease(void *sem) {
- S5IOHandle *fd = (int *)sem;
- if (sem && SENDSOCKET(fd[1], " ", 1, 0) != 1) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(0), 0, "Semrelease: write failed: %m");
- return -1;
- }
- return 0;
- }
- int semreset(void *sem, int val) {
- S5IOHandle *fd = (int *)sem;
- int nq;
- /* ok? */
- if (sem == NULL) return 0;
- #ifdef FIONREAD
- ioctl(fd[0], FIONREAD, (char *)&nq);
- if (nq == val) return 0;
- #else
- /* on some OSs fstat works on pipes, if it doesn't, it will return -1, */
- /* and we'll be ok. */
- {
- struct stat sb;
- if (fstat(fd[0], &sb) == 0 && sb.st_size == val) return 0;
- }
- #endif
- /* Need to reset it, really... */
- close(fd[0]);
- close(fd[1]);
- return semstart((int *)sem, val);
- /* Since this only gets called on HUPs, we can deal with recreating the */
- /* pipe -- It doesn't happen that often, and the old pipe should be */
- /* gone or will be as soon as the last child that has it open exits. */
- /* while (nq-- > val) semacquire(sem); while (nq++ < val) */
- /* semrelease(sem); */
- }
- void semdestroy(void *sem) {
- S5IOHandle *fd = (int *)sem;
- if (!sem) return;
- close(fd[0]);
- close(fd[1]);
- free(sem);
- }
- void *semcreate(int count) {
- S5IOHandle *fd;
- if ((fd = (int *)malloc(2 * sizeof(int)))== NULL) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(0), 0, "Semcreate: malloc failed");
- return NULL;
- }
- semstart(fd, count);
- return (void *)fd;
- }
- #endif /* not __svr4__ */