diff --git a/package/lean/luci-app-syncdial/Makefile b/package/lean/luci-app-syncdial/Makefile new file mode 100755 index 000000000..177d207a2 --- /dev/null +++ b/package/lean/luci-app-syncdial/Makefile @@ -0,0 +1,17 @@ +# +# Copyright (C) 2008-2014 The LuCI Team +# +# This is free software, licensed under the Apache License, Version 2.0 . +# + +include $(TOPDIR)/rules.mk + +LUCI_TITLE:=Virtual WAN config generator +LUCI_DEPENDS:=+kmod-macvlan +luci-app-mwan3 +PKG_VERSION:=2.0 +PKG_RELEASE:=22 + +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature +#Makefile for syncdial diff --git a/package/lean/luci-app-syncdial/luasrc/controller/syncdial.lua b/package/lean/luci-app-syncdial/luasrc/controller/syncdial.lua new file mode 100644 index 000000000..bb5f48d75 --- /dev/null +++ b/package/lean/luci-app-syncdial/luasrc/controller/syncdial.lua @@ -0,0 +1,25 @@ +--[[ +Sync Dial Luci configuration page. +Copyright (C) 2015 GuoGuo +]]-- + +module("luci.controller.syncdial", package.seeall) + +function index() + + if not nixio.fs.access("/etc/config/syncdial") then + return + end + + local page + page = entry({"admin", "network", "syncdial"}, cbi("syncdial"), _("虚拟WAN")) + page.dependent = true + + page = entry({"admin", "network", "macvlan_redial"}, call("redial"), nil) + page.leaf = true + +end + +function redial() + os.execute("killall -9 pppd") +end diff --git a/package/lean/luci-app-syncdial/luasrc/model/cbi/syncdial.lua b/package/lean/luci-app-syncdial/luasrc/model/cbi/syncdial.lua new file mode 100644 index 000000000..95e540255 --- /dev/null +++ b/package/lean/luci-app-syncdial/luasrc/model/cbi/syncdial.lua @@ -0,0 +1,37 @@ +--[[ +Sync Dial Luci configuration page. +Copyright (C) 2015 GuoGuo +]]-- + +local fs = require "nixio.fs" + +local cmd = "mwan3 status | grep -c \"is online and tracking is active\"" +local shellpipe = io.popen(cmd,"r") +local ifnum = shellpipe:read("*a") +shellpipe:close() + + +m = Map("syncdial", translate("创建虚拟WAN接口"), + translatef("使用macvlan驱动创建多个虚拟WAN口。
当前在线接口数量:")..ifnum) + +s = m:section(TypedSection, "syncdial", translate(" ")) +s.anonymous = true + +switch = s:option(Flag, "enabled", "启用") +switch.rmempty = false + +--s:option(Flag, "force_redial", "强制全部重拨", "如果有接口掉线则强制所有接口下线重拨。").rmempty = false + +wannum = s:option(Value, "wannum", "虚拟WAN接口数量") +wannum.datatype = "range(0,20)" +wannum.optional = false + +s:option(Flag, "old_frame", "使用旧的macvlan创建方式").rmempty = false + +o = s:option(DummyValue, "_redial", "重新并发拨号") +o.template = "syncdial/redial_button" +o.width = "10%" + +return m + + diff --git a/package/lean/luci-app-syncdial/luasrc/view/syncdial/redial_button.htm b/package/lean/luci-app-syncdial/luasrc/view/syncdial/redial_button.htm new file mode 100644 index 000000000..e8c4f0739 --- /dev/null +++ b/package/lean/luci-app-syncdial/luasrc/view/syncdial/redial_button.htm @@ -0,0 +1,17 @@ +<%+cbi/valueheader%> + + + + +<%+cbi/valuefooter%> diff --git a/package/lean/luci-app-syncdial/root/bin/genwancfg b/package/lean/luci-app-syncdial/root/bin/genwancfg new file mode 100755 index 000000000..d24a0ea96 --- /dev/null +++ b/package/lean/luci-app-syncdial/root/bin/genwancfg @@ -0,0 +1,143 @@ +#!/bin/sh +#macvlan及PPPoE拨号接口配置批量自动生成脚本 +#Copyright (C) 2015 GuoGuo +. /lib/functions.sh + +#检测IP列表 +chk_ip_list="$(cat /tmp/resolv.conf.auto | grep nameserver | cut -d' ' -f2 | sort -u | tr '\n' ' ') 115.239.210.27 115.239.211.112 220.181.112.244 220.181.111.188 114.114.114.114 114.114.115.115" +fw_str="wan wan6" + +#添加MWAN负载均衡相关配置 +#$1:接口名称 +mwan_cfg_add() { + #gen mwan3_interface + uci set mwan3.${1}=interface + uci set mwan3.${1}.enabled=1 + uci set mwan3.${1}.count=1 + uci set mwan3.${1}.timeout=2 + uci set mwan3.${1}.interval=5 + uci set mwan3.${1}.down=3 + uci set mwan3.${1}.up=2 + for i in $chk_ip_list + do + uci add_list mwan3.${1}.track_ip="$i" + done + uci set mwan3.${1}.reliability=1 + #gen mwan3_member + uci set mwan3.${1}_m1_w1=member + uci set mwan3.${1}_m1_w1.interface=${1} + uci set mwan3.${1}_m1_w1.metric=1 + uci set mwan3.${1}_m1_w1.weight=1 + #gen mwan3_policy + uci add_list mwan3.balanced.use_member=${1}_m1_w1 +} + +#删除MWAN负载均衡相关配置 +#$1:接口名称 +mwan_cfg_del() { + uci del mwan3.${1} + uci del mwan3.${1}_m1_w1 + uci del_list mwan3.balanced.use_member=${1}_m1_w1 +} + +#添加macvlan设备 +#$1:设虚拟备名称 $2:原始设备名称 +macvlan_dev_add() { + uci set network.macvlandev_${1}=device + uci set network.macvlandev_${1}.name=${1} + uci set network.macvlandev_${1}.ifname=${2} + uci set network.macvlandev_${1}.type=macvlan +} + +#添加PPPoE接口 +#$1:接口名称 $2:设备名称 $3:账户 $4:密码 $5:网关跃点 +pppoe_if_add() { + #gen wan if + uci set network.${1}=interface + uci set network.${1}.ifname=${2} + uci set network.${1}.proto=pppoe + uci set network.${1}.username=${3} + uci set network.${1}.password=${4} + uci set network.${1}.metric=${5} + #gen firewall + fw_str="${fw_str} ${1}" +} + +apply_cfg() { + uci commit + /etc/init.d/network restart + killall pppconnectcheck + /etc/init.d/firewall restart + mwan3 restart +} + +general_config_load() { + config_load 'syncdial' + config_get_bool enabled 'config' 'enabled' + config_get_bool old_frame 'config' 'old_frame' + [ $enabled -eq 0 ] && { + echo "Disabled.Exit now." + apply_cfg + exit 1 + } + config_get wannum 'config' 'wannum' + + config_load 'network' + config_get pppoe_user 'wan' 'username' + config_get pppoe_password 'wan' 'password' + pppoe_ifname=$(uci get network.wan.ifname) +} + +check_remove_device() { + local devcfg=${1} + [ ${devcfg::11} == 'macvlandev_' ] && uci del network.${devcfg} +} + +check_remove_interface() { + local ifcfg=${1} + [ ${ifcfg::4} == 'vwan' ] && { + uci del network.${ifcfg} + mwan_cfg_del ${ifcfg} + } +} + +general_config_remove() { + config_load network + config_foreach check_remove_device 'device' + config_foreach check_remove_interface 'interface' + [ $(uci get network.wan.proto) == "none" ] && { + uci set network.wan.proto=pppoe + } + mwan_cfg_del 'wan' + uci set firewall.@zone[1].network="wan wan6" +} + + +general_config_remove +general_config_load + +uci set network.wan.metric=40 +[ $old_frame -eq 1 ] && { + uci set network.wan.proto=none + ifname=$(uci get network.wan.ifname) + for i in $(seq 1 $wannum) + do + ip link add link $ifname name macvlan$i type macvlan + ifconfig macvlan$i hw ether $(echo $(cat /sys/class/net/$ifname/address|awk -F ":" '{print $1":"$2":"$3":"$4":"$5":" }')$(echo "" | awk -F ":" '{printf("%X\n", 16+i);}' i=$i)) + ifconfig macvlan$i up + done +} +[ $old_frame -eq 0 ] && mwan_cfg_add wan + +for i in $(seq 1 $wannum) +do + [ $old_frame -eq 0 ] && macvlan_dev_add macvlan$i $pppoe_ifname + pppoe_if_add vwan$i macvlan$i $pppoe_user $pppoe_password $((40+$i)) + mwan_cfg_add vwan$i +done + +uci set firewall.@zone[1].network="$fw_str" + +apply_cfg + +return 0 diff --git a/package/lean/luci-app-syncdial/root/etc/config/syncdial b/package/lean/luci-app-syncdial/root/etc/config/syncdial new file mode 100644 index 000000000..9adeb2d70 --- /dev/null +++ b/package/lean/luci-app-syncdial/root/etc/config/syncdial @@ -0,0 +1,7 @@ +config syncdial 'config' + option 'enabled' '0' + option 'wannum' '2' + option 'dialchk' '0' + option 'dialnum' '1' + option 'dialwait' '25' + option 'old_frame' '1' diff --git a/package/lean/luci-app-syncdial/root/etc/hotplug.d/iface/01-mvifcreate b/package/lean/luci-app-syncdial/root/etc/hotplug.d/iface/01-mvifcreate new file mode 100644 index 000000000..426341fed --- /dev/null +++ b/package/lean/luci-app-syncdial/root/etc/hotplug.d/iface/01-mvifcreate @@ -0,0 +1,16 @@ +#!/bin/sh +[ "$(uci get syncdial.config.enabled)" = "1" ] && \ + [ "$(uci get syncdial.config.old_frame)" = "1" ] && \ + [ "$DEVICE" = "$(uci get network.wan.ifname)" ] && \ + [ "$ACTION" = "ifup" ] && { + ifname=$(uci get network.wan.ifname) + wannum=$(uci get syncdial.config.wannum) + for i in $(seq 1 $wannum) + do + [ -d /sys/class/net/macvlan$i ] || { + ip link add link $ifname name macvlan$i type macvlan + ifconfig macvlan$i hw ether $(echo $(cat /sys/class/net/$ifname/address|awk -F ":" '{print $1":"$2":"$3":"$4":"$5":" }')$(echo "" | awk -F ":" '{printf("%X\n", 16+i);}' i=$i)) + ifconfig macvlan$i up + } + done +} diff --git a/package/lean/luci-app-syncdial/root/etc/uci-defaults/luci-syncdial b/package/lean/luci-app-syncdial/root/etc/uci-defaults/luci-syncdial new file mode 100755 index 000000000..5394164cc --- /dev/null +++ b/package/lean/luci-app-syncdial/root/etc/uci-defaults/luci-syncdial @@ -0,0 +1,12 @@ +#!/bin/sh +touch /etc/config/syncdial + +uci -q batch <<-EOF >/dev/null + delete ucitrack.@syncdial[-1] + add ucitrack syncdial + set ucitrack.@syncdial[-1].exec='/bin/genwancfg' + commit ucitrack +EOF + +rm -f /tmp/luci-indexcache +exit 0 diff --git a/package/network/services/ppp/Makefile b/package/network/services/ppp/Makefile index 6c615cab0..282e8f17f 100644 --- a/package/network/services/ppp/Makefile +++ b/package/network/services/ppp/Makefile @@ -35,7 +35,7 @@ endef define Package/ppp $(call Package/ppp/Default) - DEPENDS:=+kmod-ppp + DEPENDS:=+kmod-ppp +libpthread +shellsync TITLE:=PPP daemon VARIANT:=default endef diff --git a/package/network/services/ppp/files/ppp.sh b/package/network/services/ppp/files/ppp.sh index 73bc3161c..875714b35 100755 --- a/package/network/services/ppp/files/ppp.sh +++ b/package/network/services/ppp/files/ppp.sh @@ -223,7 +223,16 @@ proto_pppoe_setup() { json_get_var service service json_get_var host_uniq host_uniq +#By 蝈蝈:并发拨号同步的前期准备 + syncppp_option="" + [ "$(uci get syncdial.config.enabled)" == "1" ] && { + ppp_if_cnt=$(cat /etc/config/network | grep -c "proto 'pppoe'") + syncppp_option="syncppp $ppp_if_cnt" + shellsync $ppp_if_cnt 10 + } + ppp_generic_setup "$config" \ + $syncppp_option \ plugin rp-pppoe.so \ ${ac:+rp_pppoe_ac "$ac"} \ ${service:+rp_pppoe_service "$service"} \ diff --git a/package/network/services/ppp/patches/511-syncppp.patch b/package/network/services/ppp/patches/511-syncppp.patch new file mode 100644 index 000000000..fe58b8cc8 --- /dev/null +++ b/package/network/services/ppp/patches/511-syncppp.patch @@ -0,0 +1,214 @@ +diff -Naur ppp-2.4.5.0/pppd/chap-new.c ppp-2.4.5/pppd/chap-new.c +--- ppp-2.4.5.0/pppd/chap-new.c 2012-04-18 15:44:46.000000000 +0800 ++++ ppp-2.4.5/pppd/chap-new.c 2012-04-19 20:24:28.000000000 +0800 +@@ -37,6 +37,8 @@ + #include "chap-new.h" + #include "chap-md5.h" + ++#include "syncppp.h" ++ + #ifdef CHAPMS + #include "chap_ms.h" + #define MDTYPE_ALL (MDTYPE_MICROSOFT_V2 | MDTYPE_MICROSOFT | MDTYPE_MD5) +@@ -481,6 +483,19 @@ + p[2] = len >> 8; + p[3] = len; + ++ if (npppd > 1) { ++ if (syncppp(npppd) < 0) { ++ error("syncppp sync fail"); ++ sem_unlink(SEM_COUNT_NAME); ++ sem_unlink(SEM_BLOCK_NAME); ++ } else { ++ info("syncppp sync succeeded"); ++ } ++ } else { ++ info("syncppp not active"); ++ } ++ ++ + output(0, response, PPP_HDRLEN + len); + } + +diff -Naur ppp-2.4.5.0/pppd/Makefile.linux ppp-2.4.5/pppd/Makefile.linux +--- ppp-2.4.5.0/pppd/Makefile.linux 2012-04-18 15:44:46.000000000 +0800 ++++ ppp-2.4.5/pppd/Makefile.linux 2012-04-19 20:01:05.000000000 +0800 +@@ -13,16 +13,16 @@ + + PPPDSRCS = main.c magic.c fsm.c lcp.c ipcp.c upap.c chap-new.c md5.c ccp.c \ + ecp.c ipxcp.c auth.c options.c sys-linux.c md4.c chap_ms.c \ +- demand.c utils.c tty.c eap.c chap-md5.c session.c ++ demand.c utils.c tty.c eap.c chap-md5.c session.c syncppp.c + + HEADERS = ccp.h session.h chap-new.h ecp.h fsm.h ipcp.h \ + ipxcp.h lcp.h magic.h md5.h patchlevel.h pathnames.h pppd.h \ +- upap.h eap.h ++ upap.h eap.h syncppp.h + + MANPAGES = pppd.8 + PPPDOBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap-new.o md5.o ccp.o \ + ecp.o auth.o options.o demand.o utils.o sys-linux.o ipxcp.o tty.o \ +- eap.o chap-md5.o session.o ++ eap.o chap-md5.o session.o syncppp.o + + # + # include dependencies if present +@@ -33,7 +33,7 @@ + # CC = gcc + # + COPTS = -O2 -pipe -Wall -g +-LIBS = ++LIBS = -lpthread + + # Uncomment the next 2 lines to include support for Microsoft's + # MS-CHAP authentication protocol. Also, edit plugins/radius/Makefile.linux. +diff -Naur ppp-2.4.5.0/pppd/options.c ppp-2.4.5/pppd/options.c +--- ppp-2.4.5.0/pppd/options.c 2012-04-18 15:44:46.000000000 +0800 ++++ ppp-2.4.5/pppd/options.c 2012-04-19 20:24:49.000000000 +0800 +@@ -126,6 +126,7 @@ + bool dryrun; /* print out option values and exit */ + char *domain; /* domain name set by domain option */ + int child_wait = 5; /* # seconds to wait for children at exit */ ++int npppd = 0; /* synchronize between multiple pppd */ + struct userenv *userenv_list; /* user environment variables */ + + #ifdef MAXOCTETS +@@ -311,6 +312,10 @@ + "Set pathname of ipv6-down script", + OPT_PRIV|OPT_STATIC, NULL, MAXPATHLEN }, + ++ { "syncppp", o_int, &npppd, ++ "sync among multiple pppd when sending chap/pap respond", OPT_PRIO }, ++ ++ + #ifdef HAVE_MULTILINK + { "multilink", o_bool, &multilink, + "Enable multilink operation", OPT_PRIO | 1 }, +diff -Naur ppp-2.4.5.0/pppd/pppd.h ppp-2.4.5/pppd/pppd.h +--- ppp-2.4.5.0/pppd/pppd.h 2012-04-18 15:44:46.000000000 +0800 ++++ ppp-2.4.5/pppd/pppd.h 2012-04-19 20:25:02.000000000 +0800 +@@ -327,6 +327,7 @@ + extern bool dump_options; /* print out option values */ + extern bool dryrun; /* check everything, print options, exit */ + extern int child_wait; /* # seconds to wait for children at end */ ++extern int npppd; /* synchronize between multiple pppd */ + + #ifdef MAXOCTETS + extern unsigned int maxoctets; /* Maximum octetes per session (in bytes) */ +diff -Naur ppp-2.4.5.0/pppd/syncppp.c ppp-2.4.5/pppd/syncppp.c +--- ppp-2.4.5.0/pppd/syncppp.c 1970-01-01 08:00:00.000000000 +0800 ++++ ppp-2.4.5/pppd/syncppp.c 2012-04-18 15:46:59.000000000 +0800 +@@ -0,0 +1,75 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include "pppd.h" ++#include "syncppp.h" ++ ++int syncppp(int nproc) ++{ ++ int flags; ++ int value; ++ sem_t *block; ++ sem_t *count; ++ struct timespec ts; ++ ++ if (nproc <= 1) { ++ error("syncppp: number of pppd should be larger than 1"); ++ return -1; ++ } ++ ++ if (clock_gettime(CLOCK_REALTIME, &ts) == -1) { ++ error("clock_gettime error"); ++ return -1; ++ } ++ ts.tv_sec += SYNCPPP_TIMEOUT; ++ ++ ++ flags = O_RDWR | O_CREAT; ++ block = sem_open(SEM_BLOCK_NAME, flags, 0644, 0); ++ count = sem_open(SEM_COUNT_NAME, flags, 0644, 0); ++ if (block == SEM_FAILED || count == SEM_FAILED) { ++ error("syncppp: sem_open failed"); ++ return -1; ++ } ++ ++ if (sem_post(count) < 0) { ++ error("syncppp: sem_post failed"); ++ return -1; ++ } ++ if (sem_getvalue(count, &value) < 0) { ++ error("syncppp: sem_getvalue failed"); ++ return -1; ++ } ++ info("%d pppd have arrived, waiting for the left %d", value, nproc-value); ++ if (value >= nproc) { ++ while (nproc-1 > 0) { ++ if (sem_post(block) < 0) { ++ error("syncppp: sem_post failed"); ++ return -1; ++ } ++ nproc--; ++ } ++ } else { ++ if (sem_timedwait(block, &ts) < 0) { ++ if (errno == ETIMEDOUT) { ++ error("syncppp: sem_timewait time out"); ++ } else { ++ error("syncppp: sem_timewait error"); ++ } ++ return -1; ++ } ++ ++ } ++ ++ sem_close(count); ++ sem_close(block); ++ ++ sem_unlink(SEM_COUNT_NAME); ++ sem_unlink(SEM_BLOCK_NAME); ++ ++ return 0; ++} ++ +diff -Naur ppp-2.4.5.0/pppd/syncppp.h ppp-2.4.5/pppd/syncppp.h +--- ppp-2.4.5.0/pppd/syncppp.h 1970-01-01 08:00:00.000000000 +0800 ++++ ppp-2.4.5/pppd/syncppp.h 2012-04-18 15:46:59.000000000 +0800 +@@ -0,0 +1,3 @@ ++#define SEM_BLOCK_NAME "block" ++#define SEM_COUNT_NAME "count" ++#define SYNCPPP_TIMEOUT 5 +diff -Naur ppp-2.4.5.0/pppd/upap.c ppp-2.4.5/pppd/upap.c +--- ppp-2.4.5.0/pppd/upap.c 2012-04-18 15:44:46.000000000 +0800 ++++ ppp-2.4.5/pppd/upap.c 2012-04-19 20:26:22.000000000 +0800 +@@ -52,6 +52,8 @@ + #include "pppd.h" + #include "upap.h" + ++#include "syncppp.h" ++ + static const char rcsid[] = RCSID; + + static bool hide_password = 1; +@@ -568,6 +570,18 @@ + PUTCHAR(u->us_passwdlen, outp); + BCOPY(u->us_passwd, outp, u->us_passwdlen); + ++ if (npppd > 1) { ++ if (syncppp(npppd) < 0) { ++ error("syncppp sync fail"); ++ sem_unlink(SEM_COUNT_NAME); ++ sem_unlink(SEM_BLOCK_NAME); ++ } else { ++ info("syncppp sync succeeded"); ++ } ++ } else { ++ info("syncppp not active"); ++ } ++ + output(u->us_unit, outpacket_buf, outlen + PPP_HDRLEN); + + TIMEOUT(upap_timeout, u, u->us_timeouttime); diff --git a/package/network/services/shellsync/Makefile b/package/network/services/shellsync/Makefile new file mode 100644 index 000000000..6dce14b35 --- /dev/null +++ b/package/network/services/shellsync/Makefile @@ -0,0 +1,34 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=shellsync +PKG_VERSION:=0.2 +PKG_RELEASE:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/shellsync + CATEGORY:=Utilities + TITLE:=shellsync + DEPENDS:=+libpthread +endef + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) + $(CP) ./src/* $(PKG_BUILD_DIR)/ +endef + +define Package/shellsync/description +A tool to sync different shell scripts.Based on syncppp patch by morfast. +endef + +define Build/Compile + $(TARGET_CROSS)gcc -pthread -o $(PKG_BUILD_DIR)/shellsync $(PKG_BUILD_DIR)/shellsync.c +endef + +define Package/shellsync/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/shellsync $(1)/usr/bin +endef + + +$(eval $(call BuildPackage,shellsync)) diff --git a/package/network/services/shellsync/src/shellsync.c b/package/network/services/shellsync/src/shellsync.c new file mode 100644 index 000000000..4aef1e9ba --- /dev/null +++ b/package/network/services/shellsync/src/shellsync.c @@ -0,0 +1,106 @@ +/************************************************************************* + > File Name: shellsync.c + > Author: GuoGuo + > Mail: gch981213@gmail.com + > Created Time: 2014年11月06日 星期四 19时15分30秒 + ************************************************************************/ +#include +#include +#include +#include +#include +#include +#define SEM_BLOCK_NAME "SYNCSHELL_block" +#define SEM_COUNT_NAME "SYNCSHELL_count" +int wait_timeout; +int sync_wait(int nproc) +{ + int flags; + int value; + sem_t *block; + sem_t *count; + struct timespec ts; + + if (nproc <= 1) { + printf("sync_wait: number of processes should be larger than 1\n"); + return -1; + } + + if (clock_gettime(CLOCK_REALTIME, &ts) == -1) { + printf("clock_gettime error\n"); + return -1; + } + ts.tv_sec += wait_timeout; + + + flags = O_RDWR | O_CREAT; + block = sem_open(SEM_BLOCK_NAME, flags, 0644, 0); + count = sem_open(SEM_COUNT_NAME, flags, 0644, 0); + if (block == SEM_FAILED || count == SEM_FAILED) { + printf("sync_wait: sem_open failed\n"); + return -1; + } + + if (sem_post(count) < 0) { + printf("sync_wait: sem_post failed\n"); + return -1; + } + if (sem_getvalue(count, &value) < 0) { + printf("sync_wait: sem_getvalue failed\n"); + return -1; + } + printf("%d processes have arrived, waiting for the left %d\n", value, nproc-value); + if (value >= nproc) { + while (nproc-1 > 0) { + if (sem_post(block) < 0) { + printf("sync_wait: sem_post failed\n"); + return -1; + } + nproc--; + } + } else { + if (sem_timedwait(block, &ts) < 0) { + if (errno == ETIMEDOUT) { + printf("sync_wait: sem_timewait time out\n"); + } else { + printf("sync_wait: sem_timewait error\n"); + } + return -1; + } + + } + + sem_close(count); + sem_close(block); + + sem_unlink(SEM_COUNT_NAME); + sem_unlink(SEM_BLOCK_NAME); + + return 0; +} + +int main(int argc,char *argv[]) +{ + if(argc!=3) + { + printf("Usage: shellsync \n"); + } + else + { + int proc_num; + sscanf(argv[1],"%d",&proc_num); + sscanf(argv[2],"%d",&wait_timeout); + if(sync_wait(proc_num)<0) + { + printf("Processes sync failed.\n"); + sem_unlink(SEM_COUNT_NAME); + sem_unlink(SEM_BLOCK_NAME); + return 1; + } + else + { + printf("Processes sync succeed.\n"); + return 0; + } + } +}