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: | 270bafa39f1831713815e76d72fb8d4a0c68c6c2 |
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: 227c179b06 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: 270bafa39f user: rkeene tags: trunk | |
07:41 | Added start of TSMF service starter check-in: 836d61857f user: rkeene tags: trunk | |
Changes
Modified initrd/admin-tclkit/kitcreator-modules/system/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) {