int undos = 0, decrease = 0, alter = 0, max; 
int undos = 0, alter = 0, max; 
asmlinkage long sys_semtimedop(int semid, struct sembuf __user *tsops,			unsigned nsops, const struct timespec __user *timeout){	int error = -EINVAL;	struct sem_array *sma;	struct sembuf fast_sops[SEMOPM_FAST];	struct sembuf* sops = fast_sops, *sop;	struct sem_undo *un;	int undos = 0, decrease = 0, alter = 0, max;	struct sem_queue queue;	unsigned long jiffies_left = 0;	if (nsops < 1 || semid < 0)		return -EINVAL;	if (nsops > sc_semopm)		return -E2BIG;	if(nsops > SEMOPM_FAST) {		sops = kmalloc(sizeof(*sops)*nsops,GFP_KERNEL);		if(sops==NULL)			return -ENOMEM;	}	if (copy_from_user (sops, tsops, nsops * sizeof(*tsops))) {		error=-EFAULT;		goto out_free;	}	if (timeout) {		struct timespec _timeout;		if (copy_from_user(&_timeout, timeout, sizeof(*timeout))) {			error = -EFAULT;			goto out_free;		}		if (_timeout.tv_sec < 0 || _timeout.tv_nsec < 0 ||			_timeout.tv_nsec >= 1000000000L) {			error = -EINVAL;			goto out_free;		}		jiffies_left = timespec_to_jiffies(&_timeout);	}	max = 0;	for (sop = sops; sop < sops + nsops; sop++) {		if (sop->sem_num >= max)			max = sop->sem_num;		if (sop->sem_flg & SEM_UNDO)			undos++;		if (sop->sem_op < 0)			decrease = 1;		if (sop->sem_op > 0)			alter = 1;	}	alter |= decrease;retry_undos:	if (undos) {		un = find_undo(semid);		if (IS_ERR(un)) {			error = PTR_ERR(un);			goto out_free;		}	} else		un = NULL;	sma = sem_lock(semid);	error=-EINVAL;	if(sma==NULL)		goto out_free;	error = -EIDRM;	if (sem_checkid(sma,semid))		goto out_unlock_free;	/*	 * semid identifies are not unique - find_undo may have	 * allocated an undo structure, it was invalidated by an RMID	 * and now a new array with received the same id. Check and retry.	 */	if (un && un->semid == -1) {		sem_unlock(sma);		goto retry_undos;	}	error = -EFBIG;	if (max >= sma->sem_nsems)		goto out_unlock_free;	error = -EACCES;	if (ipcperms(&sma->sem_perm, alter ? S_IWUGO : S_IRUGO))		goto out_unlock_free;	error = security_sem_semop(sma, sops, nsops, alter);	if (error)		goto out_unlock_free;	error = try_atomic_semop (sma, sops, nsops, un, current->tgid);	if (error <= 0) {		if (alter && error == 0)			update_queue (sma);		goto out_unlock_free;	}	/* We need to sleep on this operation, so we put the current	 * task into the pending queue and go to sleep.	 */			queue.sma = sma;	queue.sops = sops;	queue.nsops = nsops;	queue.undo = un;	queue.pid = current->tgid;	queue.id = semid;	queue.alter = alter;	if (alter)		append_to_queue(sma ,&queue);	else		prepend_to_queue(sma ,&queue);	queue.status = -EINTR;	queue.sleeper = current;	current->state = TASK_INTERRUPTIBLE;	sem_unlock(sma);	if (timeout)		jiffies_left = schedule_timeout(jiffies_left);	else		schedule();	error = queue.status;	while(unlikely(error == IN_WAKEUP)) {		cpu_relax();		error = queue.status;	}	if (error != -EINTR) {		/* fast path: update_queue already obtained all requested		 * resources */		goto out_free;	}	sma = sem_lock(semid);	if(sma==NULL) {		if(queue.prev != NULL)			BUG();		error = -EIDRM;		goto out_free;	}	/*	 * If queue.status != -EINTR we are woken up by another process	 */	error = queue.status;	if (error != -EINTR) {		goto out_unlock_free;	}	/*	 * If an interrupt occurred we have to clean up the queue	 */	if (timeout && jiffies_left == 0)		error = -EAGAIN;	remove_from_queue(sma,&queue);	goto out_unlock_free;out_unlock_free:	sem_unlock(sma);out_free:	if(sops != fast_sops)		kfree(sops);	return error;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/b78755abcdf1d7667c51580a3783e16e981ed926/sem.c/clean/ipc/sem.c