From 58eda02257a89df6e05f504bdf87e578d90f3b5e Mon Sep 17 00:00:00 2001 From: Johannes Sixt Date: Sat, 1 Dec 2007 11:10:54 +0100 Subject: Compile some programs only conditionally. These programs depend on difficult to emulate POSIX functionality. On Windows, we won't compile them. Signed-off-by: Johannes Sixt --- Makefile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'Makefile') diff --git a/Makefile b/Makefile index b003e3e60a..95572efee5 100644 --- a/Makefile +++ b/Makefile @@ -273,11 +273,9 @@ EXTRA_PROGRAMS = # ... and all the rest that could be moved out of bindir to gitexecdir PROGRAMS += $(EXTRA_PROGRAMS) -PROGRAMS += git-daemon$X PROGRAMS += git-fast-import$X PROGRAMS += git-fetch-pack$X PROGRAMS += git-hash-object$X -PROGRAMS += git-imap-send$X PROGRAMS += git-index-pack$X PROGRAMS += git-merge-index$X PROGRAMS += git-merge-tree$X @@ -773,6 +771,10 @@ ifdef ZLIB_PATH endif EXTLIBS += -lz +ifndef NO_POSIX_ONLY_PROGRAMS + PROGRAMS += git-daemon$X + PROGRAMS += git-imap-send$X +endif ifndef NO_OPENSSL OPENSSL_LIBSSL = -lssl ifdef OPENSSLDIR -- cgit v1.3 From f4626df51f63d53b89ff01de54cbf7558217ea2b Mon Sep 17 00:00:00 2001 From: Johannes Sixt Date: Sat, 1 Dec 2007 21:24:59 +0100 Subject: Add target architecture MinGW. With this change GIT can be compiled and linked using MinGW. Builtins that only read the repository such as the log family and grep already work. Simple stubs are provided for a number of functions that the Windows C runtime does not offer. They will be completed in later patches. However, a fix for the snprintf/vsnprintf replacement is applied here to avoid buffer overflows. Dmitry Kakurin pointed out that access(..., X_OK) would always fails on Vista and suggested the -D__USE_MINGW_ACCESS workaround. Signed-off-by: Johannes Sixt --- Makefile | 28 ++++++++++++ compat/mingw.c | 57 +++++++++++++++++++++++ compat/mingw.h | 134 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ compat/snprintf.c | 19 ++++++-- git-compat-util.h | 13 ++++-- 5 files changed, 244 insertions(+), 7 deletions(-) create mode 100644 compat/mingw.c create mode 100644 compat/mingw.h (limited to 'Makefile') diff --git a/Makefile b/Makefile index 95572efee5..a7dafa7586 100644 --- a/Makefile +++ b/Makefile @@ -335,6 +335,7 @@ LIB_H += builtin.h LIB_H += cache.h LIB_H += cache-tree.h LIB_H += commit.h +LIB_H += compat/mingw.h LIB_H += csum-file.h LIB_H += decorate.h LIB_H += delta.h @@ -711,6 +712,33 @@ ifeq ($(uname_S),HP-UX) NO_HSTRERROR = YesPlease NO_SYS_SELECT_H = YesPlease endif +ifneq (,$(findstring MINGW,$(uname_S))) + NO_MMAP = YesPlease + NO_PREAD = YesPlease + NO_OPENSSL = YesPlease + NO_CURL = YesPlease + NO_SYMLINK_HEAD = YesPlease + NO_IPV6 = YesPlease + NO_SETENV = YesPlease + NO_UNSETENV = YesPlease + NO_STRCASESTR = YesPlease + NO_STRLCPY = YesPlease + NO_MEMMEM = YesPlease + NEEDS_LIBICONV = YesPlease + OLD_ICONV = YesPlease + NO_C99_FORMAT = YesPlease + NO_STRTOUMAX = YesPlease + NO_MKDTEMP = YesPlease + SNPRINTF_RETURNS_BOGUS = YesPlease + NO_SVN_TESTS = YesPlease + NO_PERL_MAKEMAKER = YesPlease + NO_POSIX_ONLY_PROGRAMS = YesPlease + COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat + COMPAT_CFLAGS += -DSNPRINTF_SIZE_CORR=1 + COMPAT_OBJS += compat/mingw.o compat/fnmatch.o compat/regex.o + EXTLIBS += -lws2_32 + X = .exe +endif ifneq (,$(findstring arm,$(uname_M))) ARM_SHA1 = YesPlease endif diff --git a/compat/mingw.c b/compat/mingw.c new file mode 100644 index 0000000000..075448d245 --- /dev/null +++ b/compat/mingw.c @@ -0,0 +1,57 @@ +#include "../git-compat-util.h" + +unsigned int _CRT_fmode = _O_BINARY; + +unsigned int sleep (unsigned int seconds) +{ + Sleep(seconds*1000); + return 0; +} + +int mkstemp(char *template) +{ + char *filename = mktemp(template); + if (filename == NULL) + return -1; + return open(filename, O_RDWR | O_CREAT, 0600); +} + +int gettimeofday(struct timeval *tv, void *tz) +{ + return -1; +} + +int poll(struct pollfd *ufds, unsigned int nfds, int timeout) +{ + return -1; +} + +struct tm *gmtime_r(const time_t *timep, struct tm *result) +{ + /* gmtime() in MSVCRT.DLL is thread-safe, but not reentrant */ + memcpy(result, gmtime(timep), sizeof(struct tm)); + return result; +} + +struct tm *localtime_r(const time_t *timep, struct tm *result) +{ + /* localtime() in MSVCRT.DLL is thread-safe, but not reentrant */ + memcpy(result, localtime(timep), sizeof(struct tm)); + return result; +} + +struct passwd *getpwuid(int uid) +{ + static struct passwd p; + return &p; +} + +int setitimer(int type, struct itimerval *in, struct itimerval *out) +{ + return -1; +} + +int sigaction(int sig, struct sigaction *in, struct sigaction *out) +{ + return -1; +} diff --git a/compat/mingw.h b/compat/mingw.h new file mode 100644 index 0000000000..e5c0c6ba21 --- /dev/null +++ b/compat/mingw.h @@ -0,0 +1,134 @@ +#include + +/* + * things that are not available in header files + */ + +typedef int pid_t; +#define hstrerror strerror + +#define S_IFLNK 0120000 /* Symbolic link */ +#define S_ISLNK(x) (((x) & S_IFMT) == S_IFLNK) +#define S_ISSOCK(x) 0 +#define S_IRGRP 0 +#define S_IWGRP 0 +#define S_IXGRP 0 +#define S_ISGID 0 +#define S_IROTH 0 +#define S_IXOTH 0 + +#define WIFEXITED(x) ((unsigned)(x) < 259) /* STILL_ACTIVE */ +#define WEXITSTATUS(x) ((x) & 0xff) +#define WIFSIGNALED(x) ((unsigned)(x) > 259) + +#define SIGKILL 0 +#define SIGCHLD 0 +#define SIGPIPE 0 +#define SIGHUP 0 +#define SIGQUIT 0 +#define SIGALRM 100 + +#define F_GETFD 1 +#define F_SETFD 2 +#define FD_CLOEXEC 0x1 + +struct passwd { + char *pw_name; + char *pw_gecos; + char *pw_dir; +}; + +struct pollfd { + int fd; /* file descriptor */ + short events; /* requested events */ + short revents; /* returned events */ +}; +#define POLLIN 1 +#define POLLHUP 2 + +typedef void (__cdecl *sig_handler_t)(int); +struct sigaction { + sig_handler_t sa_handler; + unsigned sa_flags; +}; +#define sigemptyset(x) (void)0 +#define SA_RESTART 0 + +struct itimerval { + struct timeval it_value, it_interval; +}; +#define ITIMER_REAL 0 + +#define st_blocks st_size/512 /* will be cleaned up later */ +#define lstat stat + +/* + * trivial stubs + */ + +static inline int readlink(const char *path, char *buf, size_t bufsiz) +{ errno = ENOSYS; return -1; } +static inline int symlink(const char *oldpath, const char *newpath) +{ errno = ENOSYS; return -1; } +static inline int link(const char *oldpath, const char *newpath) +{ errno = ENOSYS; return -1; } +static inline int fchmod(int fildes, mode_t mode) +{ errno = ENOSYS; return -1; } +static inline int fork(void) +{ errno = ENOSYS; return -1; } +static inline unsigned int alarm(unsigned int seconds) +{ return 0; } +static inline int fsync(int fd) +{ return 0; } +static inline int getppid(void) +{ return 1; } +static inline void sync(void) +{} +static inline int getuid() +{ return 1; } +static inline struct passwd *getpwnam(const char *name) +{ return NULL; } +static inline int fcntl(int fd, int cmd, long arg) +{ + if (cmd == F_GETFD || cmd == F_SETFD) + return 0; + errno = EINVAL; + return -1; +} + +/* + * simple adaptors + */ + +static inline int mingw_mkdir(const char *path, int mode) +{ + return mkdir(path); +} +#define mkdir mingw_mkdir + +static inline int waitpid(pid_t pid, unsigned *status, unsigned options) +{ + if (options == 0) + return _cwait(status, pid, 0); + errno = EINVAL; + return -1; +} + + +static inline int pipe(int filedes[2]) +{ return _pipe(filedes, 8192, 0); } + +/* + * implementations of missing functions + */ + +unsigned int sleep (unsigned int seconds); +int mkstemp(char *template); +int gettimeofday(struct timeval *tv, void *tz); +int poll(struct pollfd *ufds, unsigned int nfds, int timeout); +struct tm *gmtime_r(const time_t *timep, struct tm *result); +struct tm *localtime_r(const time_t *timep, struct tm *result); +int getpagesize(void); /* defined in MinGW's libgcc.a */ +struct passwd *getpwuid(int uid); +int setitimer(int type, struct itimerval *in, struct itimerval *out); +int sigaction(int sig, struct sigaction *in, struct sigaction *out); diff --git a/compat/snprintf.c b/compat/snprintf.c index dbfc2d6b6e..580966e56a 100644 --- a/compat/snprintf.c +++ b/compat/snprintf.c @@ -1,12 +1,25 @@ #include "../git-compat-util.h" +/* + * The size parameter specifies the available space, i.e. includes + * the trailing NUL byte; but Windows's vsnprintf expects the + * number of characters to write without the trailing NUL. + */ +#ifndef SNPRINTF_SIZE_CORR +#define SNPRINTF_SIZE_CORR 0 +#endif + #undef vsnprintf int git_vsnprintf(char *str, size_t maxsize, const char *format, va_list ap) { char *s; - int ret; + int ret = -1; - ret = vsnprintf(str, maxsize, format, ap); + if (maxsize > 0) { + ret = vsnprintf(str, maxsize-SNPRINTF_SIZE_CORR, format, ap); + /* Windows does not NUL-terminate if result fills buffer */ + str[maxsize-1] = 0; + } if (ret != -1) return ret; @@ -20,7 +33,7 @@ int git_vsnprintf(char *str, size_t maxsize, const char *format, va_list ap) if (! str) break; s = str; - ret = vsnprintf(str, maxsize, format, ap); + ret = vsnprintf(str, maxsize-SNPRINTF_SIZE_CORR, format, ap); } free(s); return ret; diff --git a/git-compat-util.h b/git-compat-util.h index c04e8baa87..da7249ac1c 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -63,17 +63,18 @@ #include #include #include -#include #include +#include +#include +#include +#ifndef __MINGW32__ +#include #include #include #include -#include #ifndef NO_SYS_SELECT_H #include #endif -#include -#include #include #include #include @@ -89,6 +90,10 @@ #include #define _ALL_SOURCE 1 #endif +#else /* __MINGW32__ */ +/* pull in Windows compatibility stuff */ +#include "compat/mingw.h" +#endif /* __MINGW32__ */ #ifndef NO_ICONV #include -- cgit v1.3 From 23326d14edbd16469453f6c3ecdd98ab90e6efb7 Mon Sep 17 00:00:00 2001 From: Johannes Sixt Date: Sat, 8 Dec 2007 20:57:25 +0100 Subject: Windows: Strip ".exe" from the program name. Before we can successfully parse a builtin command from the program name we must strip off unneeded parts, that is, the file extension. Furthermore, we must take Windows style path names into account when we parse the program name. Signed-off-by: Johannes Sixt --- Makefile | 1 + git-compat-util.h | 4 ++++ git.c | 19 ++++++++++++++++--- 3 files changed, 21 insertions(+), 3 deletions(-) (limited to 'Makefile') diff --git a/Makefile b/Makefile index a7dafa7586..9c5aae03bb 100644 --- a/Makefile +++ b/Makefile @@ -735,6 +735,7 @@ ifneq (,$(findstring MINGW,$(uname_S))) NO_POSIX_ONLY_PROGRAMS = YesPlease COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat COMPAT_CFLAGS += -DSNPRINTF_SIZE_CORR=1 + COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\" COMPAT_OBJS += compat/mingw.o compat/fnmatch.o compat/regex.o EXTLIBS += -lws2_32 X = .exe diff --git a/git-compat-util.h b/git-compat-util.h index ab762c79ee..a9a85be89d 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -114,6 +114,10 @@ #define PATH_SEP ':' #endif +#ifndef STRIP_EXTENSION +#define STRIP_EXTENSION "" +#endif + #ifndef has_dos_drive_prefix #define has_dos_drive_prefix(path) 0 #endif diff --git a/git.c b/git.c index 59f0fcc1f2..871b93ca7e 100644 --- a/git.c +++ b/git.c @@ -369,6 +369,16 @@ static void handle_internal_command(int argc, const char **argv) { "pack-refs", cmd_pack_refs, RUN_SETUP }, }; int i; + static const char ext[] = STRIP_EXTENSION; + + if (sizeof(ext) > 1) { + i = strlen(argv[0]) - strlen(ext); + if (i > 0 && !strcmp(argv[0] + i, ext)) { + char *argv0 = strdup(argv[0]); + argv[0] = cmd = argv0; + argv0[i] = '\0'; + } + } /* Turn "git cmd --help" into "git help cmd" */ if (argc > 1 && !strcmp(argv[1], "--help")) { @@ -386,8 +396,8 @@ static void handle_internal_command(int argc, const char **argv) int main(int argc, const char **argv) { - const char *cmd = argv[0] ? argv[0] : "git-help"; - char *slash = strrchr(cmd, '/'); + const char *cmd = argv[0] && *argv[0] ? argv[0] : "git-help"; + char *slash = (char *)cmd + strlen(cmd); const char *cmd_path = NULL; int done_alias = 0; @@ -396,7 +406,10 @@ int main(int argc, const char **argv) * name, and the dirname as the default exec_path * if we don't have anything better. */ - if (slash) { + do + --slash; + while (cmd <= slash && !is_dir_sep(*slash)); + if (cmd <= slash) { *slash++ = 0; cmd_path = cmd; cmd = slash; -- cgit v1.3 From 8512439af25c93942d569d250d49d135d8b7062b Mon Sep 17 00:00:00 2001 From: Johannes Sixt Date: Fri, 30 Nov 2007 22:28:38 +0100 Subject: Windows: Use a relative default template_dir and ETC_GITCONFIG With this definition the templates and system config file will be found irrespective of the installation location. Signed-off-by: Johannes Sixt --- Makefile | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Makefile') diff --git a/Makefile b/Makefile index 9c5aae03bb..7233160743 100644 --- a/Makefile +++ b/Makefile @@ -739,6 +739,8 @@ ifneq (,$(findstring MINGW,$(uname_S))) COMPAT_OBJS += compat/mingw.o compat/fnmatch.o compat/regex.o EXTLIBS += -lws2_32 X = .exe + template_dir = ../share/git-core/templates/ + ETC_GITCONFIG = ../etc/gitconfig endif ifneq (,$(findstring arm,$(uname_M))) ARM_SHA1 = YesPlease -- cgit v1.3 From 0b50b860a505d4a1d6fa595a400f3968333e7128 Mon Sep 17 00:00:00 2001 From: Johannes Sixt Date: Tue, 1 Jan 2008 22:15:21 +0100 Subject: When installing, be prepared that template_dir may be relative. Since the Makefile in the template/ subdirectory is only used to install the templates, we do not simply pass down the setting of template_dir when it is relative, but construct the intended destination in a new variable: A relative template_dir is relative to gitexecdir. Signed-off-by: Johannes Sixt --- Makefile | 9 ++++++++- templates/Makefile | 8 ++++---- 2 files changed, 12 insertions(+), 5 deletions(-) (limited to 'Makefile') diff --git a/Makefile b/Makefile index 7233160743..a2a19a85f0 100644 --- a/Makefile +++ b/Makefile @@ -205,7 +205,7 @@ GITWEB_FAVICON = git-favicon.png GITWEB_SITE_HEADER = GITWEB_SITE_FOOTER = -export prefix bindir gitexecdir sharedir template_dir htmldir sysconfdir +export prefix bindir gitexecdir sharedir htmldir sysconfdir CC = gcc AR = ar @@ -1297,6 +1297,13 @@ remove-dashes: ### Installation rules +ifeq ($(firstword $(subst /, ,$(template_dir))),..) +template_instdir = $(gitexecdir)/$(template_dir) +else +template_instdir = $(template_dir) +endif +export template_instdir + install: all $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)' $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(gitexecdir_SQ)' diff --git a/templates/Makefile b/templates/Makefile index bda9d13505..9f3f1fc352 100644 --- a/templates/Makefile +++ b/templates/Makefile @@ -8,12 +8,12 @@ INSTALL ?= install TAR ?= tar RM ?= rm -f prefix ?= $(HOME) -template_dir ?= $(prefix)/share/git-core/templates +template_instdir ?= $(prefix)/share/git-core/templates # DESTDIR= # Shell quote (do not use $(call) to accommodate ancient setups); DESTDIR_SQ = $(subst ','\'',$(DESTDIR)) -template_dir_SQ = $(subst ','\'',$(template_dir)) +template_instdir_SQ = $(subst ','\'',$(template_instdir)) all: boilerplates.made custom @@ -46,6 +46,6 @@ clean: $(RM) -r blt boilerplates.made install: all - $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(template_dir_SQ)' + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(template_instdir_SQ)' (cd blt && $(TAR) cf - .) | \ - (cd '$(DESTDIR_SQ)$(template_dir_SQ)' && umask 022 && $(TAR) xf -) + (cd '$(DESTDIR_SQ)$(template_instdir_SQ)' && umask 022 && $(TAR) xf -) -- cgit v1.3