aboutsummaryrefslogtreecommitdiffstats
path: root/toolbox
diff options
context:
space:
mode:
authorKen Sumrall <ksumrall@android.com>2011-04-05 20:46:30 -0700
committerKen Sumrall <ksumrall@android.com>2011-04-05 20:50:03 -0700
commit795165bc1512faa121083c6bf3ce6f6d83ce59e6 (patch)
tree1f678ef8dcca5faf185169501c8d26d296825a99 /toolbox
parent18247d74be9d0d4d6f1ae25bdd198e5dbf522af8 (diff)
downloadsystem_core-795165bc1512faa121083c6bf3ce6f6d83ce59e6.tar.gz
system_core-795165bc1512faa121083c6bf3ce6f6d83ce59e6.tar.bz2
system_core-795165bc1512faa121083c6bf3ce6f6d83ce59e6.zip
Add the touch command to toolbox.
I wrote this to test my fix to support utime(2) system calls in the sdcard fuse filesystem for stingray, and decided to finish sprucing it up and make it part of toolbox. In an effort to keep it small, it doesn't accept dates a la touch, but just a time_t value. Change-Id: I5dd011cd2e34d0cc605d6f40e46b96a8c949f194
Diffstat (limited to 'toolbox')
-rw-r--r--toolbox/Android.mk1
-rw-r--r--toolbox/touch.c87
2 files changed, 88 insertions, 0 deletions
diff --git a/toolbox/Android.mk b/toolbox/Android.mk
index ff01172e..76542a63 100644
--- a/toolbox/Android.mk
+++ b/toolbox/Android.mk
@@ -54,6 +54,7 @@ TOOLS := \
vmstat \
nandread \
ionice \
+ touch \
lsof
LOCAL_SRC_FILES:= \
diff --git a/toolbox/touch.c b/toolbox/touch.c
new file mode 100644
index 00000000..b8ab310d
--- /dev/null
+++ b/toolbox/touch.c
@@ -0,0 +1,87 @@
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <fcntl.h>
+
+static void usage(void)
+{
+ fprintf(stderr, "touch: usage: touch [-alm] [-t time_t] <file>\n");
+ exit(1);
+}
+
+int touch_main(int argc, char *argv[])
+{
+ int i, fd, aflag = 0, mflag = 0, debug = 0, flags = 0;
+ struct timespec specified_time, times[2];
+ char *file = 0;
+
+ specified_time.tv_nsec = UTIME_NOW;
+
+ for (i = 1; i < argc; i++) {
+ if (argv[i][0] == '-') {
+ /* an option */
+ const char *arg = argv[i]+1;
+ while (arg[0]) {
+ switch (arg[0]) {
+ case 'a': aflag = 1; break;
+ case 'm': mflag = 1; break;
+ case 't':
+ if ((i+1) >= argc)
+ usage();
+ specified_time.tv_sec = atol(argv[++i]);
+ if (specified_time.tv_sec == 0) {
+ fprintf(stderr, "touch: invalid time_t\n");
+ exit(1);
+ }
+ specified_time.tv_nsec = 0;
+ break;
+ case 'l': flags |= AT_SYMLINK_NOFOLLOW; break;
+ case 'd': debug = 1; break;
+ default:
+ usage();
+ }
+ arg++;
+ }
+ } else {
+ /* not an option, and only accept one filename */
+ if (i+1 != argc)
+ usage();
+ file = argv[i];
+ }
+ }
+
+ if (! file) {
+ fprintf(stderr, "touch: no file specified\n");
+ exit(1);
+ }
+
+ if (access(file, F_OK))
+ if ((fd=creat(file, 0666)) != -1)
+ close(fd);
+
+ if ((mflag == 0) && (aflag == 0))
+ aflag = mflag = 1;
+
+ if (aflag)
+ times[0] = specified_time;
+ else
+ times[0].tv_nsec = UTIME_OMIT;
+
+ if (mflag)
+ times[1] = specified_time;
+ else
+ times[1].tv_nsec = UTIME_OMIT;
+
+ if (debug) {
+ fprintf(stderr, "file = %s\n", file);
+ fprintf(stderr, "times[0].tv_sec = %ld, times[0].tv_nsec = %ld\n", times[0].tv_sec, times[0].tv_nsec);
+ fprintf(stderr, "times[1].tv_sec = %ld, times[1].tv_nsec = %ld\n", times[1].tv_sec, times[1].tv_nsec);
+ fprintf(stderr, "flags = 0x%8.8x\n", flags);
+ }
+
+ return utimensat(AT_FDCWD, file, times, flags);
+}
+