Check-in [4b855bb7b2]
Overview
Comment:Started processing "umask" and "cwd" arguments Updated to have 30sec (currently hard-coded) timeout for starting processes
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 4b855bb7b2f754fd75d909218fa02793b377950a
User & Date: rkeene on 2012-09-09 21:18:51
Other Links: manifest | tags
Context
2012-09-09
21:25
Updated to allow (and require) user to specify timeout check-in: 504add9c98 user: rkeene tags: trunk
21:18
Started processing "umask" and "cwd" arguments Updated to have 30sec (currently hard-coded) timeout for starting processes check-in: 4b855bb7b2 user: rkeene tags: trunk
07:41
Added start of TSMF service starter check-in: 4626ecb025 user: rkeene tags: trunk
Changes

Modified system.c from [af68cfea10] to [dc2605a233].

  1874   1874   		close(sock_v6);
  1875   1875   	}
  1876   1876   
  1877   1877   	return(retval);
  1878   1878   }
  1879   1879   
  1880   1880   static int tclsystem_tsmf_start_svc(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
  1881         -	Tcl_Obj *filename_obj, *env_obj, *logfile_obj, **env_entry_objv;
         1881  +	struct timeval select_timeout;
         1882  +	Tcl_WideInt umask_tclval;
         1883  +	Tcl_Obj *filename_obj, *env_obj, *logfile_obj, **env_entry_objv, *cwd_obj, *umask_obj, *user_obj, *group_obj, *sri_obj;
  1882   1884   	pid_t child, child_pgid = -1;
  1883   1885   	ssize_t read_ret;
  1884   1886   	time_t currtime;
         1887  +	mode_t umask_val;
  1885   1888   	char *argv[3], *envv[512];
  1886         -	char *logfile, *filename;
         1889  +	char *logfile, *filename, *cwd, *user, *group;
  1887   1890   	char logmsg[2048];
  1888         -	int pipe_ret, setsid_ret, execve_ret, tcl_ret;
         1891  +	fd_set read_fdset;
         1892  +	int pipe_ret, setsid_ret, execve_ret, tcl_ret, select_ret;
  1889   1893   	int null_fd, log_fd, tmp_fd, max_fd;
  1890   1894   	int env_entry_objc;
  1891   1895   	int fds[2], fd;
  1892   1896   	int status;
  1893   1897   	int idx;
  1894   1898   
  1895   1899   	/* 1. Parse arguments */
................................................................................
  1897   1901   	if (objc != 9) {
  1898   1902   		Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"::system::syscall::tsmf_start_svc sri filename logfile env cwd umask user group\"", -1));
  1899   1903   
  1900   1904   		return(TCL_ERROR);
  1901   1905   	}
  1902   1906   
  1903   1907   	/* 1.b. Identify Tcl_Objs to use for each argument */
         1908  +	sri_obj = objv[1];
  1904   1909   	filename_obj = objv[2];
  1905   1910   	logfile_obj = objv[3];
  1906   1911   	env_obj = objv[4];
         1912  +	cwd_obj = objv[5];
         1913  +	umask_obj = objv[6];
         1914  +	user_obj = objv[7];
         1915  +	group_obj = objv[8];
  1907   1916   
  1908   1917   	/* 1.c. Store string arguments */
  1909   1918   	filename = Tcl_GetString(filename_obj);
  1910   1919   	logfile = Tcl_GetString(logfile_obj);
         1920  +	cwd = Tcl_GetString(cwd_obj);
         1921  +	user = Tcl_GetString(user_obj);
         1922  +	group = Tcl_GetString(group_obj);
  1911   1923   
  1912         -	/* 1.d. Process environment */
         1924  +	/* 1.d. Integer objects */
         1925  +	tcl_ret = Tcl_GetWideIntFromObj(interp, umask_obj, &umask_tclval);
         1926  +	if (tcl_ret != TCL_OK) {
         1927  +		return(tcl_ret);
         1928  +	}
         1929  +
         1930  +	umask_val = umask_tclval;
         1931  +
         1932  +	/* 1.e. Process environment */
  1913   1933   	tcl_ret = Tcl_ListObjGetElements(interp, env_obj, &env_entry_objc, &env_entry_objv);
  1914   1934   	if (tcl_ret != TCL_OK) {
  1915   1935   		return(tcl_ret);
  1916   1936   	}
  1917   1937   
  1918   1938   	for (idx = 0; idx < MIN(env_entry_objc, sizeof(envv) / sizeof(envv[0]) - 1); idx++) {
  1919   1939   		envv[idx] = Tcl_GetString(env_entry_objv[idx]);
................................................................................
  1939   1959   	if (child != 0) {
  1940   1960   		/* 4.parent. Get PGID from child */
  1941   1961   		/* 4.parent.a. Close write end of pipe -- we are read-only */
  1942   1962   		close(fds[1]);
  1943   1963   		fd = fds[0];
  1944   1964   
  1945   1965   		/* 4.parent.b. Read process group ID of child from pipe */
  1946         -		read_ret = read(fd, &child_pgid, sizeof(child_pgid));
         1966  +		select_timeout.tv_sec = 30;
         1967  +		select_timeout.tv_usec = 0;
         1968  +
         1969  +		FD_ZERO(&read_fdset);
         1970  +		FD_SET(fd, &read_fdset);
         1971  +
         1972  +		select_ret = select(fd + 1, &read_fdset, NULL, NULL, &select_timeout);
         1973  +		if (select_ret == 0) {
         1974  +			/* On timeout, terminate starting process */
         1975  +			child_pgid = getpgid(child);
         1976  +			if (child_pgid != ((pid_t) -1)) {
         1977  +				kill(-child_pgid, SIGKILL);
         1978  +			}
         1979  +
         1980  +			Tcl_SetObjResult(interp, Tcl_NewStringObj("timeout", -1));
         1981  +
         1982  +			return(TCL_ERROR);
         1983  +		}
         1984  +
         1985  +		if (select_ret > 0) {
         1986  +			read_ret = read(fd, &child_pgid, sizeof(child_pgid));
         1987  +		}
  1947   1988   
  1948   1989   		/* 4.parent.c. Close read end of pipe */
  1949   1990   		close(fd);
  1950   1991   
  1951   1992   		/* 4.parent.d. Verify read was meaningful */
  1952   1993   		if (read_ret != sizeof(child_pgid)) {
  1953   1994   			Tcl_SetObjResult(interp, Tcl_NewStringObj("failed to communicate with started service", -1));
................................................................................
  1978   2019   		write(fd, &child_pgid, sizeof(child_pgid));
  1979   2020   
  1980   2021   		_exit(0);
  1981   2022   	}
  1982   2023   
  1983   2024   	/* 6. Setup environment */
  1984   2025   	/* 6.a. Set umask */
  1985         -	/* XXX: TODO */
  1986         -	umask(022);
         2026  +	umask(umask_val);
  1987   2027   
  1988   2028   	/* 6.b. Set working directory */
  1989         -	/* XXX: TODO */
  1990         -	chdir("/");
         2029  +	chdir(cwd);
  1991   2030   
  1992   2031   	/* 6.c. Open log file for stderr and stdout */
  1993   2032   	log_fd = open(logfile, O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
  1994   2033   
  1995   2034   	/* 6.d. Open "/dev/null" for stdin */
  1996   2035   	null_fd = open("/dev/null", O_RDONLY);
  1997   2036   	if (null_fd < 0 || log_fd <0) {